Should web tests have fixtures?

Hello everybody

A few years ago I worked with RoR and I really loved it. Since aber 2 years or so I didn't do any webmaster work anymore, though.

Now I have a new job where CakePHP is used, some sort of RoR for PHP.

CakePHP - though quite nice for a PHP framework - is annoying me again and again, and sadly the Google Groups Mailing List doesn't offer me any help for my questions which I'm posting since days...

The main subject for these posts is testing, because I want to add a good testing battery to an existing CakePHP application (right, shame on the developers who didn't do this yet!).

But it turns out testing seems to be quite a hassle with CakePHP - at least web testing! What I want to do is the following: I want to write web tests that test the basic actions of my website, e.g. CRUD a model. For this I need some data already populating my database, which are fixtures. In CakePHP there do exist fixtures, but only for unit testing, and NOT for web testing. CakePHP doesn't even think web testing needs its own test database (or at least I couldn't get any answer that would prove something else from the folks of CakePHP's Google Group... testing really seems to be a neglected or at least "braaand new thing" in the CakePHP world)!

So what I wanted to know from you, folks (because I don't remember and I don't have the possibility to check it out for myself at the moment):

Does RoR have the possibility to use fixtures for web testing? Or am I completely on the wrong track, and CakePHP's doing everything the right way?

Thanks a lot for answers, Joshua

Joshua Muheim wrote:

Does RoR have the possibility to use fixtures for web testing? Or am I completely on the wrong track, and CakePHP's doing everything the right way?

I'm not exactly sure what you mean by "web testing."

Here are the various levels of testing that Rails supports (Test::Unit):

1. Model (Unit tests) 2. Functional (Controller tests) 3. Integration (Controller + View tests)

RSpec (http://rspec.info/) is also popular and breaks things down a little differently:

1. Model specs 2. Controller specs 3. View specs 4. Helper specs

RSpec typically relies on a third party story runner for implementing, what Test::Unit calls "integration tests," called Cucumber (http://cukes.info/).

There are other frameworks that are popular as well (e.g. Shoulda).

FIXTURES ARE BAD!!!

Most of the Rails developers I know have completely stopped using fixtures to generate test data. Fixtures are difficult to deal with and cause more problems than they are worth.

Fortunately there are now a few really great fixture replacement frameworks. The ones I'm most familiar with are Factory Girl (GitHub - thoughtbot/factory_bot_rails: Factory Bot ♥ Rails) and Machinist (GitHub - notahat/machinist: Fixtures aren't fun. Machinist is.).

As far as using fixture data for what you are calling "web tests" I would actually advise against it in most cases. For most tests (or specs) above model/unit level it's best to use mocking. Using mocks instead of real model objects helps to isolate your tests from issues at the database level.

There are a number of really good mocking frameworks to choose from. RSpec has it own built-in mocking framework, but can also use a number of third-party mocking frameworks as well.

For more information on mocking see: http://rspec.info/documentation/mocks/

Here's an overview of a number of options for testing in Rails: http://upstre.am/tag/mocha/

Thanks for your answer, Robert.

I'm not exactly sure what you mean by "web testing."

I mean the integration tests, where one programs a browser to do some stuff, e.g. "open website", "enter stuff into form", "press submit", "assert pattern xy exists" etc.

Here are the various levels of testing that Rails supports (Test::Unit):

1. Model (Unit tests) 2. Functional (Controller tests) 3. Integration (Controller + View tests)

FIXTURES ARE BAD!!!

You mean that the theory behind fixtures is bad (use predefined test data), or that the way Rails offers the use of fixtures is bad?

As far as using fixture data for what you are calling "web tests" I would actually advise against it in most cases. For most tests (or specs) above model/unit level it's best to use mocking. Using mocks instead of real model objects helps to isolate your tests from issues at the database level.

Sounds interesting, I will take a look into that.

Thanks for your useful answer - it's better than any answer I got on the CakePHP mailing list yet (and it came a lot faster to me, too)...

Joshua Muheim wrote:

Thanks for your answer, Robert.

I'm not exactly sure what you mean by "web testing."

I mean the integration tests, where one programs a browser to do some stuff, e.g. "open website", "enter stuff into form", "press submit", "assert pattern xy exists" etc.

Cucumber has great integration with webrat and capybara for such testing.

Here are the various levels of testing that Rails supports (Test::Unit):

1. Model (Unit tests) 2. Functional (Controller tests) 3. Integration (Controller + View tests)

FIXTURES ARE BAD!!!

You mean that the theory behind fixtures is bad (use predefined test data), or that the way Rails offers the use of fixtures is bad?

I mean use factories instead of fixtures (as Rails defines the term "fixtures").

fixtures are hard to maintain and impractical comprared to factories, factories are pluging/gems that create object dinamicly as needed so you can do thing like this

i have 100 users

with that the factory will create on the fly 100 users and you can later change that 100 to 1000 .

radhames brito wrote:

fixtures are hard to maintain and impractical comprared to factories, factories are pluging/gems that create object dinamicly as needed so you can do thing like this

i have 100 users

with that the factory will create on the fly 100 users and you can later change that 100 to 1000 .

Sounds very, very interesting. Thanks a lot for this hint.

look at this

Factory.define :user do |f| f.sequence(:username) { |n| “user#{n}” } f.sequence(:email) { |n| “test#{n}@example.com” } f.association :company f.password “password” f.password_confirmation { |u| u.password } f.sequence(:name) { |n| “test#{n}” } f.sequence(:last_name) { |n| “test_l#{n}” } f.sequence(:cedula) { |n| “0011357433#{n}” } end

with this factory_girl will create all the user you want as you can see it accepts a sequence and will create ad many user as needed