MarkUs Blog

MarkUs Developers Blog About Their Project

Archive for the ‘Rails’ tag

MarkUs 0.8.0 is out!

with one comment

The summer started two months ago and I am very proud to announce to you the latest release of MarkUs, version 0.8.0.

We have added a lot of great features : 🙂

Changelog

  • We are now using Rails 2.3.8, the latest version of the 2.3.x tree
  • Some bug fixes on submission dates and grace period credits
  • Python and Ruby Scripts in order to help users to interact with MarkUs through the API
  • Displaying and annotating images
    • A lot of accessibility features have been implemented :

    • Missing labels & Better focus on forms
    • Adding annotations in downloaded code from students repository
    • Re-arrange criteria using keyboard
  • MarkUs is now completely internationalized and a French translation is available

So what are you waiting for? Get MarkUs 0.8.0 right now!

Contributors:
Diane Tam
Dina Sabied
Evan Browning
Anton Braverman
Nelle Varoquaux
Bryan Shen
Severin Gehwolf
Mike Conley
Benjamin Vialle

I hope I didn’t forget someone. 🙂

Written by Benjamin Vialle

July 7th, 2010 at 11:20 am

Fixture replacement

with 4 comments

One of the things I’ve done since I joined the project, was to look at how we could make the test suite cleaner and more up-to-date.

That task implied some test debugging, and one annoying thing I bumped into was fixtures. A little internet roaming showed that I’m not alone to be uneasy with them.

Some interesting fixture definition can be found if you follow the first link:

Accessories fixed to structures or land in such a way that they can’t be independently moved without damage to themselves, or the property housing them.

Which applies strangely well to how I fell about fixtures when I use them.

Some Bad Smells

While writing tests, how many times have you asked yourself questions like:

  • Which student was part of group_1?
  • Was assignement_1 submitted?
  • Was student_3 a member of group_3 or group3? (this one is a good example of maintainability issues)
  • Am I going break dozens of tests if modify that fixture field?

To me, fixtures feature the following problems:

  • They make necessary to explore multiple files to understand a particular test;
  • It’s even more complicated to figure out the links between records;
  • They generate more data than needed by any test case;
  • They open the way to tests that pass alone but fail in the suite;
  • Editing a particular fixture may have side-effects in many tests;
  • It is a common statement that all of the above should not be problems if you maintain your fixtures adequately. But I found fixtures are hard to maintain.

The alternatives

Exploring for alternatives I stumbled upon the following projects (reduced the list to those that looked appealing):

I did read about them all, but have not tried them all. A short report on how my experiences went follows.

First attempt – FactoryGirl

My first tries were with FactoryGirl. Influenced by the fact that we were already satisfied with Shoulda and that it got the best rating on the Ruby Toolbox.

I did face some problems though. For instance, “building” an assignment was “building” a SubmissionRule that couldn’t be saved because the assignment_id field was nil. I did not manage to make it build in the correct order.

I am certainly not stating this is impossible. Maybe it’s just that I did not caught the FactoryGirl philosophy quick enough. I probably was missing something.

There were also issues with the way we generate fake memory repositories in the test_helper, but I believe we are going to get those whatever the fixture replacement we opt to use.

Second attempt – Machinist

Then I went with Machinist. First good thing I noticed about it was its syntax. It is much lighter and fun to use that FactoryGirl’s. So I did applied myself in writing blueprints. They are the Machinist artefact that let us tell him how we want our objects to be generated, supplying default values that we can override later according to our particular needs not having to mention the data we do not care about when writing a test.

The whole process is really neat. I created a review request so that you can all take a peek at how I made things work. There still are no blueprints for each of our model object, but I managed to (easily) write working blueprints for many of our classes. I would approximate, twice the number of classes (without hassle) in half the time compared to FactoryGirl.

Once more, I do not want to sound like bashing on FactoryGirl, which definitely look like a great tool and that a lot of people out there are using. I am simply reporting on my experience, and, to me, the bottom line is, Machinist came a lot more naturally.

As for FactoryGirl, Machinist does not happily coexists with fixtures (partly because of fake test repositories), enforcing the idea that if we replace the fixtures, we’ll have to completely migrate our test suite — which makes sense since it all depends on fixtures[1]. This is huge work ahead.

What is to be Gained?

First things that come to mind:

  • Easier to maintain test suite;
  • Reduced side-effects when modifying;
  • More test readability — Tremendous enhancements have been made in that field since the beginning of the semester, but there is always room to do better;

What is to be lost?

We can expect some performance loss (during test execution) if we switch to a data generator (whatever which one). This is bad. But if we want our unit tests to run fast, we should consider letting them be real unit tests and not hit the database at all. Then we could have, say, model tests that verify the relation between our objects using generated data.

Temporary Final Word

An eventual transition from fixtures to, say, Machinist, would take quite some time and would introduce even more inconsistencies in the test suite until completed. That definitely has to be kept in mind. This is no piece of cake. But the final product would most probably be a better/stronger/easier to maintain/easier to read test suite which is not something we should overlook.

My vote? Let’s pack all the courage we got[1] and sail toward a fixture-less world for the benefit of the generations to come!

——–

  1. An Agile development valued practice.

Written by gabrielrl

December 4th, 2009 at 6:51 pm

Quick Word on Test Taxonomy

with one comment

One thing (among lots of others) I have learned about tests during last semester is that, depending on the environment (or the culture you’re developing in) tests get different names.

Here’s an example where Rails’ naming conventions differ from what I have learned in my QA course[1]:

Rails’ Unit Tests are not Unit Tests

Considering a unit test should test an object in complete isolation, it is a breach to that rule to have a “unit” test access the database. Rails’ unit tests are really functional tests where we make sure that the model behaves accordingly (for one) and that its mapping with the database is correct (for two). Another thing about unit tests is that they should be fast to run. Under 30 seconds is a generally good standard (varying depending on the environment). Let me guess, you need somewhat more than 30 seconds to run rake test:units on MarkUs. For example, on my machine I get a run time of approximately 31 seconds, which would be good, if it was not for the fact that it does not include the database setup time as well as (I believe) setup and teardown time between each test[2].

Side-note: I also get 1 error and 1 failure. It makes me want to emphasize that fast-to-run tests get ran more often. It the tests are not used, they loose their ability to help find bugs early, get deprecated and more of a burden that a great tool.

On the other hand. Every model object is so tightly coupled with ActiveRecord that one could argue that we do not really want to test our model classes without ActiveRecord participating.

Anyway, this is an example of what I was stating in the first paragraph. In this case, it is commonly accepted, in Rails’ culture, that, what I could refer to as “open box integration testing of models and ActiveRecord”[3] should be called “a unit test”. The later has some clear advantages over the former and the most important thing is to make sure that everyone is speaking the same language among the team.

Refactoring the test/ folder

As Adam told us during code sprint. It is a common practice, among Rails’ developer teams, to refactor the test folder on the very start of a new project. One way of doing this could give something like:

  • test/ remains test/
  • unit/ becomes model/
  • functional/ becomes controller/
  • unit/ gets added (and contains model unit tests that does not hit the database)
  • functional/ gets added (and contains selenium tests)
  • acceptance/ gets added (and contains cucumber tests)

Being loose

I have myself been pretty loose all these times I have reffered to Cucumber tests simply as acceptance tests. If you dig a little, you’ll find that I was more specifically talking about “user acceptance” tests.

Convention Over Elite Correctness

It’s written up there, but the key thing is to speak the same language among the team. You’ve experienced it, Rails is all about conventions. Keeping the usual setting may help newcomers to the project, but used Rails developers, to understand exactly what is supposed to go where (and what they can expect to find where) when it comes to test.

On the other hand, from what I can tell, newcomers to the project also are newcomers to Ruby and Rails, which, I believe, leaves the way open for a little structure refactoring.

——–

  1. Which, in turn, was not proposing an absolute answer to “how a specific test should be named?” but rather focused on providing us with the necessary tools (read: knowledge) to efficiently and intelligently test the software we develop.
  2. Does anybody know?
  3. and I am no authority on the question. I also intentionally made it too long for its own good 😉

Written by gabrielrl

December 4th, 2009 at 5:03 pm

How to Install Seed_fu

without comments

Today, we got a pretty awesome cursory code review from Mike Gunderloy.

One thing he suggested, was that we switch from running a sloppy Ruby script to seed our database with initial data, to something like seed_fu.

So, how do we install Seed_fu?  It took me a while to figure it out, actually, since I’d never installed a Rails plugin from GitHub before.

Anyhow, here’s how you do it:

From your application root:


script/plugin install git://github.com/mbleigh/seed-fu.git

Easy.

Written by m_conley

June 11th, 2009 at 5:07 pm

Posted in OLM on Rails

Tagged with , ,

Prototype/Ajax.Request -> Rails – The Plot Thickens Part 2

with one comment

Still no solution in sight.  I’ve tried creating a brand new Rails project, and the behaviour persists there as well.  I’m convinced it’s a problem with Rails though, and not a problem in my machine.

Let’s go over the facts again:

  • I have Rails 2.1.0 installed on an Ubuntu 8.04 Hardy Heron Tablet PC
  • I’m using a Postgres database on the OLM project
  • Using Prototype JS library V 1.6.0.1
  • We’re using Mongrel, not WeBRICK
  • Using Ajax.Request with the ‘POST’ method does not pass any parameters to the params hash in the target controller
  • It works with GET though!
  • When using POST, I can see the parameters if I inspect the request object – they’re in @parameters, which I cannot seem to access
  • POSTing seems to work on other computers, using the same OLM code checked out from the repository
  • I’ve tried a complete reinstall of Rails, with the same result

Maybe my uninstall assumption is wrong:  what’s the best way to completely purge Rails from my machine?  I essentially followed these steps before:

Thoughts from anybody?

Thanks,

-Mike

Written by m_conley

November 21st, 2008 at 3:04 am

Problems getting Prototype/Ajax.Request to talk to Rails

with 2 comments

I’m totally losing my mind over this problem, because it seems so simple, and yet I can’t seem to figure it out.

Here’s the situation:

I’ve begun linking up my Rubric Manager UI prototype to the Rails backend.  On this UI is a big “Save Changes” button, that implements all of the changes to the Rubric in one shot.  That button is linked to a Javascript function called save_changes.

Here is save_changes:

function save_changes() {
/* ....some code...*/
  new Ajax.Request('/checkmark/rubrics/modify',
  {
      method:'post',
      parameters: {authenticity_token: '<%=form_authenticity_token%>', key: 'value'},
      onSuccess: function(transport){
      console.log("Success");
  },
  onFailure: function(){ console.error('Something went wrong...') }
  });
/*...some more code...*/
}

So this seems alright to me.  I have to include the “authenticity_token” in my parameters because Rails seems to be using some type of internal request forgery protection.

When I click on “Save Changes”, however, Firebug tells me that the page I POSTED to threw an “InvalidAuthenticityToken” exception.  So that’s frustrating – I’m clearly passing the token in my parameters.  I created a tiny test form and POSTed to the same ‘modify’ method with the authenticity token as a hidden value, and it worked just fine.

So what gives?

Geofrey helped me get by the InvalidAuthenticityToken problem by inserting the authenticity_token variable into the URL string of the Ajax.Request target:

function save_changes() {
/* ....some code...*/
  new Ajax.Request('/checkmark/rubrics/modify?authenticity_token=43e5f5e3fbf3248b2a403f828010f8544ad36dbf',
  {
      method:'post',
      parameters: {key: 'value'},
      onSuccess: function(transport){
      console.log("Success");
  },
  onFailure: function(){ console.error('Something went wrong...') }
  });
/*...some more code...*/
}

But NOW, the parameter “key => value” isn’t being passed to the rails param map in the RubricsController.  I know this, because I inspect the param map in the Controller with the following code:

def modify
    render :text => params.inspect  
end

And here’s what is returned from the AJAX call:

{"authenticity_token"=>"43e5f5e3fbf3248b2a403f828010f8544ad36dbf", "action"=>"modify", "controller"=>"rubrics"}

So what’s going on?  Anyone.

-Mike

Written by m_conley

November 14th, 2008 at 12:41 am

Posted in Uncategorized

Tagged with , , , , ,

Developing a Rubric for OLM on Rails

with 2 comments

Hey all – I’m Mike, and I’ve just started working on the OLM on Rails project.  My first task is to develop the Rubric models, controllers, and user experience, and I’m going to share some musings on it.

Ok, so first off, here’s the idea:  A professor creates an Assignment, and has to have a marking scheme to go along with it.  The Rubric that she develops will be used by the TA’s to mark the assignments.  Sounds pretty simple.

I’m still getting my thinking wrapped together here, so I’m just going to muse for a bit.  Here are some thoughts, rules, and caveats:

  • Creation of a Rubric is a separate event from creating an Assignment.  So if an Assignment exists, it does not imply that an associated Rubric exists yet
  • A Rubric consists of an arbitrary number of criteria to grade the student
  • Each criterion has a weight assigned to it (ie: 0.25, 0.5, etc)
  • Each criterion has a number of levels that can be achieved by a student.  By default, these levels are 0, 1, 2, 3, and 4 – with 0 being the worst performance, and 4 being the best.  We’re considering having the ability to add additional levels, to improve flexibility
  • An assignment cannot be marked until a Rubric has been created
  • A Rubric is not valid unless all of the weights of its criteria sum to 1.0 (100%)
  • The total number of marks achievable on an Assignment equals the sum of each criterion weight, multiplied by the maximum level of that criterion.  This does not include possible bonus marks, which are not handled by the Rubric
  • Assigning weights to criteria is going to be a little tricky, interface-wise.  While it’s tempting to just use a simple text-box, and trust the user to input the weights manually, it’d be nice for something a little more elegant and user friendly.
  • Some professors may want a simpler way of inputting this information quickly, for instance, by uploading a file describing what they want.  Andrew has suggested that users upload a YAML file… something worth thinking about.

That’s all I’ve really got rolling in my head about it right now.

So, what have I done?  I’ve created two new models:  RubricCriteria and RubricLevel.  A RubricCriteria is assigned to a single Assignment.  A RubricLevel is assigned to a single RubricCriteria.  Piece of cake.

I’ve also created some basic unit tests for these models.  I think I’m going to start thinking about user interfaces now, because I think it will give me some hints on what I’ll want the Controller to do.  I might upload some of my sketches later.

Cheers,

-Mike

Written by m_conley

October 8th, 2008 at 12:43 pm

Posted in OLM on Rails

Tagged with , , , , , ,

Switching Rails to PostgreSQL

with one comment

Since most of the web applications we develop here uses PostgreSQL, we’ve decided to port our environment to use postgres instead. Here I outline how I managed to get rails and PostgreSQL 8.3 up and running on Ubuntu 8.04.

1. Install PostgreSQL

If you haven’t already, try typing:

sudo apt-get install postgresql postgresql-client postgresql-contrib libpq-dev

Make sure that the installation completed successfully by typing psql --version. Current version is 8.3.3. libpq-dev is important since the postgres gem needs it, so make sure that we have that installed even if you have postgresql installed already.

2. Install PostgreSQL adapter for ruby

Update your rubygem first by typing sudo gem update --include-dependencies. You then need to install ruby-pg, which superseded the now-obsolete ruby-postgres gem (which can’t even compile postgres 8.3 due to a compilation bug). To install postgres gem, type:

sudo gem install postgres

3. Create a PostgreSQL user

By default, the user in the rails DB config file is the project name. Thus we can create this user by going into the postgres console

sudo su postgres -c psql

Once in the psql console, type (including the quotes)

create user "<user_name>" with [superuser] password '<password>';

Include the superuser option if needed, usually easier for development when working on your own computer. Verify that the CREATE ROLE message was displayed then exit the console.

4. Change PostgreSQL Authentication

When executing some of the database commands, you might encounter a FATAL: ident authentication failed error. To avoid this, you need to edit your pg_hba.conf (found in /etc/postgresql/8.3/main in Ubuntu 8.04) and change the authentication scheme. Open the file with root privilege and change

# "local" is for Unix domain socket connections only
local all all ident sameuser

to

# "local" is for Unix domain socket connections only
local all all md5

Then restart your postgres server by typing sudo /etc/init.d/postgresql-8.3 restart

5. Create the databases

to create the database we can use the createdb shell command, by typing on prompt:

createdb <project_name>_development -U <user_name> -W

or, if user does not have superuser account, from the psql console (by sudo’ing as postgres from before) typing:

create database <project_name>_development owner <user_name>;

and give privilege to the user by typing:

grant all privileges on database <database_name> to <user_name>;

Do the same thing for creating <project_name>_test for the test database.

5.5 Install phppgadmin (optional)

To make your life easier, there’s a php console for developing with postgres called phppgadmin, derived from its MySQL counterpart, phpmyadmin. phpmyadmin is still a lot better interface, but phppgadmin is better than nothing at all. Assuming you have PHP and apache2 installed, install phppgadmin by typing:

sudo apt-get install phppgadmin

and create a symlink for apache:

sudo ln -s /etc/phppgadmin/apache.conf /etc/apache2/conf.d/phppgadmin.conf

Reload apache by typing sudo /etc/init.d/apache2 reload and go to http://localhost/phppgadmin/ to play around with your new tool.

6. Generate a database config file for PostgreSQL

If you’re starting from scratch, the easiest way is to create your application using

rails <project_name> -d postgresql

However, if we’re migrating to postgres from a current rails application, then the easiest way is to just create another rails application of the same name but on a different directory. Go to a directory where your current rails application is not located and create a rails application of the same name using above command. Once that’s created, just copy the database config file to your old rails application by copying:

mv <original_project_path>/config/database.yml <original_project_path>/config/database.yml.old

cp <project_name>/config/database.yml <original_project_path>/config

Once copied, open database.yml on a text editor and fill in the database details we just created.

Epilogue

One of the problems I encountered was figuring out which postgresql adapter to use. ruby-postgres wasn’t working with postgres 8.3 so I regressed back to 8.2, only to find out postgres adapter exists. Not much documentation exists since it’s fairly new and a lot of people I guess is still in psql-8.2. The other one is the dreaded FATAL: ident authentication failed error you get when starting to use psql on Ubuntu. Again, thanks to Jeff and the Dr. Project documentation, we finally got it working.

And finally, psql-8.3 seems to break the implicit cast being done from the previous 8.2 before.  So now, when I try to find matches where numbers are stored as string, I get the following error:

ERROR:  operator does not exist: character varying = integer

The column being declared as string does not match the passed integer argument, which should be converted to String in the first place.  Thus I had to explicitly cast it to a String before using.

For more information regarding PostgreSQL and Ruby on Rails, see the official wiki.

Written by Geofrey

August 12th, 2008 at 10:22 am

Migrate Your Tests

without comments

Rails has a nice way of maintaining versions of your database schema through ActiveRecord:Migration.  This lets you modify your existing schema without the hassle of manually copying the same schema to all the different deployed instances that you have, and does this automatically for you.

When I usually change the schema, I usually drop all the tables and recreate them using:

rake db:migrate VERSION=0
rake db:migrate

and then repopulate my development DB environment using a script I use.  However it turns out that this doesn’t migrate your test environment automatically with it. I tried creating a simple test of making sure that my ActiveRecord validation works.  However, I ended up getting this error:

test_numericality_group_limit(AssignmentTest):
NoMethodError: undefined method `group_limit=' for #<Assignment:0xb7242018>
/var/lib/gems/1.8/gems/activerecord-2.1.0/lib/active_record/attribute_methods.rb:251:in `method_missing'
test/unit/assignment_test.rb:11:in `test_numericality_group_limit'
/var/lib/gems/1.8/gems/activesupport-2.1.0/lib/active_support/testing/setup_and_teardown.rb:33:in `__send__'
/var/lib/gems/1.8/gems/activesupport-2.1.0/lib/active_support/testing/setup_and_teardown.rb:33:in `run'

After hours of finding the bug, I found out that you have to migrate your test DB environment as well, by executing the following:

rake db:schema:dump
rake db:test:prepare

This will copy the schema that you have right now in your development environment, and copy it to your test environment.

Written by Geofrey

August 6th, 2008 at 10:49 am

Pay Attention to Little Things

with one comment

On testing:

If you ever tried running your tests and find yourself getting the error:

your_controller_test.rb:3:in `require': no such file to load -- test_helper (LoadError)
from your_controller_test.rb:3

it’s probably because the generated require call, require test_helper is not being properly recognized.  Instead of the default require 'test_helper', replace it with:

require File.dirname(__FILE__) + '/../test_helper'

If you’re doing functional testing, make sure that the controller being tested is also required (e.g. add the line require 'your_controller' on top).  Be sure that you also have installed the package libtest-unit-ruby (if using Linux), before testing.

Also, thanks to Jeff Balogh, make sure that you append test_ on all your test cases to make sure that they actually run (I know it’s obvious, but it’s nice to be reminded once in a while).

On database constraints:

If you want to enforce foreign key constraints, remember to create the required indexes first.  ActiveRecord Migration supports this using add_index.  This only applies if the column being referred to is not a primary key, if it is then there’s no need to create the index. Once this is set, you can now enforce foreign keys using ActiveRecord Migrations by implementing this.

On implementing sessions:

By default, the rails session handler stores session information on a file in the server.  This can cause scalability issues in the long run if file space runs out or when using multiple servers.  Thus, it’s recommended to use :active_record_store instead. To do this make sure that you do the following:

  • execute rake db:sessions:create to add a create table migration for sessions
  • execute rake db:migrate to apply the new schema
  • change session store to active session store by adding this line to config/environment.rb:

config.action_controller.session_store = :active_record_store

  • Make sure that you comment out or add this line to your ApplicationController:

protect_from_forgery :secret => <32_hex_digit_secret_key>

Here are also some helpful links regarding sessions and implementing it:

Written by Geofrey

July 29th, 2008 at 4:01 pm