1

Im having difficulty deciding or understanding the best approach to testing in Laravel.

I really like the behavioural side of PHPSpec testing, although it is just not compatible with testing Eloquent models or anything related to an active record ORM.

When testing things like service providers PHPSpec seems like the way to go.

** Is it desirable to test models with something like PHPUnit, then test other non ORM layers such as service providers with something like PHPSpec? ***

AndrewMcLagan
  • 13,459
  • 23
  • 91
  • 158

2 Answers2

5

I don't know Laravel, but reading problems people have with unit testing it tells me there's a lot of design issues in there. I understood that those problematic features of Laravel are optional, so there's hope!

See my comparision of PhpSpec vs PhpUnit in an answer of another question: First Shot at Testing Laravel 4 apps (PHPSpec/BDD vs. PHPUnit/TDD)

I'm guessing you'll face lots of problems using PhpSpec with Laravel, and often you'll have to avoid specing Laravel specific quirks, or avoiding them (facades are optional, you can use proper dependency injection). I'd aim on having as much code as possible independent from the framework and properly unit test them. Then, you can have a thin layer of framework glue code, covered with functional or integration tests. Apply the dependency injection.

As an example taken from the land of Symfony and Doctrine, I usually don't write specs for Doctrine repositories. Well, I only expect they implement a certain interface. That's all. The rest is covered with my acceptance tests. There is no much value in verifying that repositories use query builder to produce an expected query. No point really.

Going back to the tools, I can see myself mixing different kind of testing tools for different kinds of testing:

  • phpspec - unit tests - I'll write most of the tests on this level
  • behat - acceptance tests
  • phpunit - integration and functional tests - I'll have a small number of these, as they're fragile and slow.
Community
  • 1
  • 1
Jakub Zalas
  • 35,761
  • 9
  • 93
  • 125
  • Hi there mate, what problems exactly? The Laravel community is very BDD and TDD driven. I see them as a clean coders community. So what is the SUT and how do they approach it? – Skid Kadda Dec 21 '14 at 11:18
  • I suppose it's caused by the trend nowadays, really popular in Laravel community most likely thanks to Jeffrey Way's strong impact there and doing good marketing for both **phpspec** and **behat**, that you should test your code. There is number of people, who have not tested their code so far and they're trying hard to change that, thus they face these kind of problems. – Jarek Tkaczyk Dec 21 '14 at 13:15
3

This really has little to do with Laravel specifically and is actually a fundamental problem with ActiveRecord as a pattern. When you use ActiveRecord you sacrifice testability. ActiveRecord is irreconcilably linked to database persistence.

If you are looking to use a test-first approach I recommend using a different approach to persistence. Write your objects to function together. Then attach persistence later with something like Doctrine.

If you want to use ActiveRecord anyway, then you're going to need to do things a bit different. Laravel doesn't force the use of Eloquent. But, it does ship with it out of the box. ActiveRecord is a tool that's more or less appropriate for writing CRUD applications. If you're doing something more complicated, I would suggest Doctrine.

Shawn McCool
  • 1,207
  • 8
  • 8