Practical 2
0. Finish Practical Sheet 1. Run the tests (rake test
) to make
sure everything works fine. If an error report claims that "MyString"
is missing from the asset pipeline, find the file products.yml
in the folder
test/fixtures
and change the value Mystring
for the two image_url
attributes in this file to ruby.jpg
. In this way, test data refer to images that
are actually contained in the folder app/assets/images
.
1. Validation. Validators can be used in the model to automatically validate properties of data when entered into the data base. Rails allows to validate various aspects of data objects. A standard requirement on certain fields might be that they are filled in the first place. The presence of values in fields can be tested as follows. Add the following line to the product model (in the file …).
This will ensure the presence of data in the
:title
, :description
, and :image_url
fields.
Try to enter a new product with any (or all) of these fields empty
and watch the effect.
2. The list of products should not contain two items with the same title. The uniquness of values for a particular field can be tested as follows. Below the validator from the previous paragraph, add the line
to the product model, then try and enter two products with the same title.
3. Validators are capable of ensuring very specific aspects of data. The following line
when added to the product model, will not allow products to have a price of zero or less. Test it.
4. Finally, here is an example of a validator that uses
a Ruby regular expression (%r{\.(gif|jpg|png)$}i
)
to specify that the URL for a product image
ends with one of three possible extensions, lower or upper case.
It also specifies the error message to be used in case this rule is violated. Try it out.
4a. If all works fine, commit the changes to your local git
repository, and push them to the github
cloud.
5. Let’s make sure that after introducing all of these safety measures, the application is still working as expected. Enter the command
and study the report it produces. Hmmm … this used to go through without failures …. What could it be that broke the (automatically generated) unit tests?
6. The reported failures concern the product create
and update
actions. The testing of these actions, as specified in the file
test/functional/products_controller_test.rb
make use of a product
called :one
. Identify the places in that file which refer to this product.
The object is defined as a fixture in the file
test/fixtures/products.yml
. Fixtures are specially designed data
for test purposes. They are formulated in the rather self-explaining
YAML language.
All those fixtures are loaded into a test database,
before the actual tests are carried out.
The validators above require all products to have different titles,
the fixtures don’t. Change the data so that the titles of one
and two
are different.
What else is wrong with product one
(and two
)? Fix this in the
fixtures file and run the test suite to see if it succeeds.
7. Open the test/functional/products_controller_test.rb
and
study the failing test that "should create product"
.
It looks like it tries to enter an exact copy of @product
(which was created from the fixture one
) into the database
(on top of the fixture data already in there). Why is that bound to
fail?
Replace the title of the new product (in the post
) command by
something like "New Book"
and run the tests again until they all
succeed.
7a. If all works fine, commit the changes to your local git
repository, and push them to the github
cloud:
8. Unit Testing. Rails provides tools to ensure that the application is working as expected. The technical term for this type of validation (which checks the software, rather than the data it deals with) is Unit Testing.
Unit tests reside in the (automatically generated) file
test/models/product_test.rb
. When you open the file you’ll find
nothing but a placeholder.
Insert the following test into the ProductTest
class:
This test will create a new product, with empty components. Validation requires that all components are filled, therefore this product should currently be invalid. Specifically, it should have errors relating to each and every component. That’s what is tested here.
9. Testing the price. Each product should have a positive price.
Formulate a further test (in product_test.rb
) as follows.
This checks that for invalid prices like -1 and 0, the product is invalid, and
carries an error message.
Do a rake test
and see how it goes.
10. For the next test, we use a loop over a list of strings.
In ruby, an array of words can be specified without quotes
(or separating commas) by using the %w
operator.
We can then use this functionality to test a variety of different filenames, some ok, some bad:
11. We can add our own test data to the fixture files. Add
to the product fixtures (which file?).
12. And we can refer to these fixtures by name (:ruby
).
In the product model, there is a validator that looks after the uniqueness of product titles. In order to test whether that works, you can create a product that has the same title as a product already in the (test) database, and check whether saving of this product fails. Add the following test:
and then run the test again. (Note the logic behind this: if the product is invalid, this test succeeds!)
12a. Finally, if all the tests work as desired, commit the changes
to your local git
repository, and push them to the github
cloud.
13. Any questions about the code in these examples? As evidence for your participation in this practical, add a comment below …