Media Programming: Web Technology

Website of Prof. Dr. Barne Kleinen, Professor for Media Informatics (Bachelor/Master) at HTW Berlin

Example Project for Web Technology - Week 3

     <prev next>

Week 3

Testing, Setting up a Deployment Workflow, and some Ruby

1. Create at least one happy-path feature test for each person on your team. Use Capybara.

I demonstrate this on the story

  • A user kann log an habit as completed on that day by simply clicking on a button in the habit list.

Before I start working on that, I should clean up the generated tests and create some test data for the Habits.

2. Test cleanup

Clean up the generated test files (those generated by rails generate scaffold) that you don’t need. Run rails test to see which tests are failing. Make sure that all tests are running before actually creating tests on your own! (It might be useful to keep some of the generated tests around while you haven’t implemented enough tests to be confident that they cover enough of your application - we’ll see an excellent example of this later!)

rails test

I get errors because of my model change (column last was deleted), so I have to look at the third step right away:

Error:
LogEntriesControllerTest#test_should_get_edit:
ActiveRecord::Fixture::FixtureError: table "habits" has no column named "last".

I keep the tests for now as, while their not doing much, they exercise the code that I don’t have tests for yet.

3. Create test data for the tests using fixtures.

Rails has created fixtures for you if you used the scaffold generator. Mine got broken when I refactored last_done by moving it to an association.

For setting up your fixtures, see the API Documentation on Fixtures: ActiveRecord::FixtureSet

See commit week-3-1 for the fix and the fixtures using the association. I’ve also added a model test to ensure the association is correctly set up.

(back to: )1. Create at least one happy-path feature test for each story you’ve implemented so far. Use Capybara.

I demonstrate this on the story

  • A user kann log an habit as completed on that day by simply clicking on a button in the habit list.

Steps:

  • add the capybara gem and capybara dsl to your tests - see the Capybara doc and my commit week-3-2
  • create the test.
  • use the launchy gem to save_and_open_page if stuck - see week-3-3

I’ve modified the page to include an id for the button to click - this makes the tests less brittle. For the actual test see commit week-3-4.

4. Create a model test.

If you have implemented functionality in your model, implement a unit test on the for that method. I’ve implemented a setter that actually modifies the association, so I write a test for that:

@habit.last_log_date = Date.today

See week-3-5. Note that I only check on the behaviour of habit, I’m only testing Habit’s public interface, as that’s the interface I actually use in my application, leaving it to Habit how it actually stores it’s log.

(I’m leaving the one association test as an example for you).

If you haven’t implemented any functionality in your model, maybe you find something that should go in the model? If not, just write tests that test if the associations are set up correctly.

5. Create seed data for playing around in development mode, and also some if you need/want seed data in production.

see db/seed.rb for an example.

6. Set up automated integration tests on travis ci for your project. Include a “build passing” button in your readme.

Go to https://travis-ci.org and set up a user account/ log in using your github account. See https://docs.travis-ci.com/user/languages/ruby/ for settings.

What I did:

  • granted travis access to the organisation media-programming-rails https://github.com/settings/connections/applications/
  • went to travis-ci.org, Account (upper right), sync account, chose organisation and flicked on the repository (organisation did not show up in the list, but it was possible to access it by entering the url https://travis-ci.org/profile/media-programming-rails manually)
  • created travis configuration files. As I’m using rvm and have a .ruby-version file anyway, I use that for travis. Travis runs rake as default script, I could alter it to rails test but as rails test is the rake default task, I leave it at that.
  • switched (and merged) to master
  • pushed to github
  • wait for first build on https://travis-ci.org/media-programming-rails/example-app
  • as you can see, it took me 3 tries to get the first running build on travis.

7. Set up an Automated Deployment to Heroku for your project.

Heroku has a detailed documentation on how to create and deploy a rails app to heroku: https://devcenter.heroku.com/articles/getting-started-with-rails5

The following steps worked for me:

  • create an account on heroku.com
  • add pg gem for postgres database. week-3-7
  • (re-)installed the heroku toolbelt
  • heroku login
  • heroku create
  • heroku rename mediaprogramming
  • git push heroku master
  • heroku open

Yields an error. This is because I don’t have a page for / ! https://mediaprogramming.herokuapp.com/habits works, though. I also realize that I have forgotten to migrate the database:

  • heroku run rails db:migrate
  • heroku run rails db:seed (if applicable)

I get a couple of warnings:

I’ve decided to ignore them mostly for now, just added the ruby version to the Gemfile.

8. For the bored: set up a build matrix testing both against postgres and sqlite on travis

And, indeed, The build passes for sqlite and fails for postgres!

See the log of Build 4, the job for postgres.

The generated controller delets an habit, and postgres (or rather the pg gem) throws an exception PG::ForeignKeyViolation because there’s a dangling LogEntry which references the deleted habit. In fact, I haven’t taken care about how to delete habits at all. As log_entrys make no sense without the habit, I add an dependent: :destroy to the association.

The error was visible on Heroku: If you deleted an habit on heroku, you get an error message: (you have to look in the logs using heroku logs ):

Thus, “travis postgres fix 1: use habit without log_entry” really makes things worse as the tests now pass on travis, but the bug is still in production.

9. Automatically Deploy every successful Build from Travis.

See Deployment Doc on travis. This worked for me:

  • installed travis gem: gem install travis

  • have travis automatically add and encrypt heroku’s api key:

    travis encrypt $(heroku auth:token) --add deploy.api_key

  • edited travis.yml deployment part

  • push to github

You can check the heroku deployments with:

`heroku releases`

to see which commit is actually deployed on heroku.

Note: you only need this condition if you have a second build for the sqlite database. on: condition: “$DB = postgres”