Presentation is loading. Please wait.

Presentation is loading. Please wait.

28-Apr-15 Unit Testing in Rails Testing Database Actions.

Similar presentations


Presentation on theme: "28-Apr-15 Unit Testing in Rails Testing Database Actions."— Presentation transcript:

1 28-Apr-15 Unit Testing in Rails Testing Database Actions

2 Testing the database Rails projects typically involve manipulating a database Testing with actual data, which you do not control, is infeasible There are likely legal issues as well You need to populate the test database with carefully designed data Creating the database with SQL each time is inefficient YAML provides a human-readable way of populating the test database Rails unit tests can be set to re-initialize the database for each test Some database tables might not be changed by testing The tests may involve only reading the database The database itself may be read-only Re-initializing the database for each test is slow and inefficient Rails unit tests can be set to not re-initialize the database for each test

3 YAML YAML can be taken as an acronym for either Yet Another Markup Language YAML Ain’t Markup Language The purpose of YAML is to represent typical data types in human-readable notation Structure is indicated by indentation with spaces; tabs are not allowed

4 YAML example 1 Rails uses YAML for configuring the database A typical entry in a.yml file would look like this: development: adapter: mysql database: cookbook host: localhost username: root password: This describes the development database Each line in the above defines a key-value pair The values are strings; they don’t need to be quoted

5 YAML example 2 Rails also uses YAML for describing the contents of databases An example might look like this: one: id: 1 category_id: 1 title: pizza description: CB's favorite lunch date: instructions: Phone pizza joint. Pay delivery guy. Chow down! two: id: 2 category_id: 2 title: iced tea date: The above example (adapted from describes hashes one and two of simple values: Strings, integers, dates Hashes can also be represented in brace notation: {name: John Smith, age: 33} Other types of data can also be represented

6 String literals String values do not need to be quoted Block literals (multiline strings) can be introduced with a pipe (“ | ”) or greater-than (“ > ”) symbol The pipe preserves line ends and spacing: street: | 123 Tornado Alley Suite 16 The greater-than symbol allows text wrapping: specialDelivery: > Follow the Yellow Brick Road to the Emerald City. Pay no attention to the man behind the curtain.

7 Lists Lists are represented by single dashes (“ - ”): movies: - Casablanca - North by Northwest - Notorious

8 Casting YAML automatically detects simple types In the rare instances where casting is necessary, explicit casting can be performed with !! Examples: a: 123 # an integer b: "123" # a string, disambiguated by quotes c: # a float d: !!float 123 # also a float via explicit data type prefixed by (!!) e: !!str 123 # a string, disambiguated by explicit type f: !!str Yes # a string via explicit type g: Yes # a boolean True h: Yes we have No bananas # a string, "Yes" and "No" # dismabiguated by context

9 Creating a test database You can begin by using SQL to create an (empty) test database: mysql -u root -p (When prompted for a password, just hit Enter) create database myApp_test; grant all on MyApp_test.* to exit You can begin by giving commands to SQL to create a nonempty test database: mysql MyApp_development

10 Copying an existing database schema You can copy the database schema (not the actual records) from the development database to the test database: rake db:test:clone_structure

11 Creating a fixture file If you used scaffolding, you already have a file test/fixtures/ table_name.yml for each table in your database schema Example: # Read about fixtures at yamlin5minutes: id: 1 name: Yaml in 5 minutes url: wikipedia: id: 2 name: Wikipedia article on YAML url: If you don't have a YAML file already, you can create one in any text editor

12 Creating test files If you used scaffolding, you already have a file test/unit/ table_name.rb for each table in your database schema Example: require File.dirname(__FILE__) + '/../test_helper' class RecipeTest < Test::Unit::TestCase fixtures :recipes # Replace this with your real tests. def test_truth assert true end end If you don't have a unit test file already, you can create one in a text editor Note: The keyword __FILE__ stands for the file this code is in test_helper is just a convenient place to put code used by many tests

13 Creating tests The idea of a unit test is that you call a method (or methods) in the model, then specify what the result should be In “ordinary” unit tests, you test the return value of a method In database tests, you frequently have to access the database to get the result Your test methods must all begin with test_ and take no parameters Example: def test_total_cost_of_order;...; end If a method doesn’t begin with test_, it won’t be called automatically You then test the result with one or more of the various assert methods (see next slide) The unit test framework does all the rest of the work If your test methods modify the database, so that it should be reloaded after each test, use: fixtures :table_name

14 Assertions assert( boolean, message=nil ) assert_block( message="assert_block failed" ) {||... } assert_equal( expected, actual, message=nil ) assert_in_delta( expected_float, actual_float, delta, message="" ) assert_instance_of( klass, object, message="" ) assert_kind_of( klass, object, message="" ) assert_match( regexp, string, message="" ) assert_nil( object, message="" ) assert_no_match( regexp, string, message="" ) assert_not_equal( expected, actual, message=nil ) assert_not_nil( object, message="" ) assert_not_same( expected, actual, message=nil ) assert_nothing_raised( *args ) {||... } assert_same( expected, actual, message="" ) flunk( message="flunked ") Plus a few others....

15 Useful methods I: Creating and saving records Here’s one way to create a record (in memory): my_record = MyClass.new; my_record.col_1 = value_1; my_record.col_2 = value_2; Here’s an equivalent way: my_record = MyClass.new( :col_1 => value_1, :col_2 => value_2 ) Here’s how to save the newly created record: my_record.save Here’s how to create and save all in one go: my_record = MyClass.create( :col_1 => value_1, :col_2 => value_2 ) Here’s how to delete a record: my_record.destroy Here’s how to find out how many records are in the database: n = MyClass.count

16 Useful methods I: Reading records Here are some simple ways to get a record from the database: my_record = MyClass.find(:first) Returns the first record in the database my_records = MyClass.find(:all) Returns an array of all the records in the database my_record = MyClass.find( id ) Returns a record with the given id my_records = MyClass.find( id_1, id_2,...) Returns an array of records with the given ids

17 Useful methods II: Reading records You won’t find these methods in the Rails API, because they are generated, based on the column names in your table record = MyClass.find_by_ col_1 ( value_1 ) If col_1 is the name of a column in the database, this returns a record whose value in that column is value_1. record = MyClass.find_all_by_ col_1 ( value_1 ) If col_1 is the name of a column in the database, this returns an array of records whose value in that column is value_1. record = MyClass.find_by_ col_1 _and_ col_2 ( value_1, value_2 ) If col_1 and col_2 are the names of columns in the database, this returns a record whose value in col_1 is value_1 and whose value in col_2 is value_2. record = MyClass.find_all_by_ col_1 _and_ col_2 ( value_1, value_2 ) If col_1 and col_2 are the names of columns in the database, this returns an array of records whose value in col_1 is value_1 and whose value in col_2 is value_2.

18 Useful methods III: Updating records Here’s how to update a record in the database: my_record = MyClass.find( id ) my_record. col_2 = value_17 my_record.save The save method uses the id field of the record to determine if the record already exists in the table If the record exists, it is updated If the record doesn’t exist, it is created In fact, save just calls another method, create_or_update

19 Example test method def test_create_and_destroy initial_rec_count = Category.count new_rec = Category.new new_rec.save assert_equal(initial_rec_count + 1, Category.count) new_rec.destroy assert_equal(initial_rec_count, Category.count) end

20 The End


Download ppt "28-Apr-15 Unit Testing in Rails Testing Database Actions."

Similar presentations


Ads by Google