1 / 20

Unit Testing in Rails

Unit Testing in Rails. Testing Database Actions. 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

nida
Download Presentation

Unit Testing in Rails

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 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: 2007-05-09 instructions: Phone pizza joint. Pay delivery guy. Chow down!two: id: 2 category_id: 2 title: iced tea date: 2007-05-09 • The above example (adapted fromhttp://www.oreillynet.com/lpt/a/7086) describes hashesone 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: 123.0 # 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 'ODBC'@'localhost'; exit • You can begin by giving commands to SQL to create a nonempty test database: • mysql MyApp_development <create.sql • (create.sql is a file containing the appropriate commands)

  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.ymlfor each table in your database schema • Example: • # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.htmlyamlin5minutes: id: 1 name: Yaml in 5 minutes url: http://yaml.kwiki.org/?YamlInFiveMinuteswikipedia: id: 2 name: Wikipedia article on YAML url: http://en.wikipedia.org/wiki/YAML • 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.rbfor 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 endend • 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_17my_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

More Related