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 G. 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 M. 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)…

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 .

Joshua M. 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”).

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 [email protected]” }
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