My Laravel Tests were Failing because of my App URL

In my role as Senior Software Engineer at Liquid Web, I’ve gotten to get back to my roots of not only doing WordPress, which has been great. In particular, I’m getting back into Laravel, getting to build real web applications in an environment that makes testing a breeze (aside: if you haven’t checked out Adam Wathan’s Test Driven Laravel course, I cannot recommend it enough!).

I ran into an interesting problem today, however, when I updated the APP_URL variable in my .env file: running my [previously 100% green] test suite, I was getting random errors and failures within my feature tests that I hadn’t been seeing before. Controller actions weren’t responding properly, model relationships weren’t always behaving, and redirects following actions were hit-or-miss.

Naturally, I assumed I had broken something in my code (after all, the tests pass consistently on Travis CI). After doing a git diff and seeing no notable changes, I switched back to the master branch and ran the suite again, only to see the same errors occurring. My repository, which was all green in our CI environment, was failing when running the exact same code.

I updated all of my Composer dependencies. I tried dumping all of the caches. I even tore down and rebuilt my Laravel Homestead environment, but these tests just kept failing.

Since version control wasn’t showing any differences between my environment and what runs in Travis CI, I decided I needed to look at the files that aren’t tracked by Git, starting with the .env file.

For those who haven’t worked with .env files before, these files contain environment-specific configuration, which is then loaded into PHP (and thus Laravel) via phpdotenv. This helps ensure that database credentials, hostnames, and more are kept out of version control and only set in the environment(s) where they’re applicable.

In my case, my .env file looked pretty normal — I had added a few custom variables for features I had built into this application, but the default settings were identical to the .env.sample file that ships with Laravel with one exception: the APP_URL variable had been changed from “http://localhost” to “http://my-app-name”.

“Surely setting the application URL isn’t what’s breaking my tests,” I thought, but I was running out of ideas and dreading digging into the internals of why these tests were failing. I restored APP_URL to the default value and suddenly my test suite was green. Change it back, tests break. What. The. Heck?

It seems that the test suite picks up the values from the .env file, and that doesn’t always work out well when running Laravel’s feature tests (especially when POST-ing to an endpoint). I haven’t had the time to dig into it and file a formal bug report yet, but I have been able to get around it by explicitly setting the APP_URL environment variable in my phpunit.xml file, within the <php> node:

This explicitly sets the APP_URL to “http://example.com” within the testing environment, overriding anything that might be in your local .env file.

Hopefully this helps someone else struggling with randomly-breaking tests. If you find yourself with time to dig into it, please feel free to comment here and/or file a bug report with the Laravel core team!

Leave a Reply