The danger of tunnel vision


I can remember when I started my first web development in a professional setting just after I left university. Times were simple: you work in PHP as there were no good alternatives for server code and in the frontend most of your time was not spent on waiting on npm install, but was spent on adding polyfills and hacky javascript hacks to get everything working in every browser, including IE6. I can remember writing my own javascript framework that basically worked with rendering HTML to a string and just update the page with jQuery html() method, because that was the fastest way to update dynamically in all browsers, including IE6.

There is still one constant in PHP that was already applicable back then: you write tests with the phpunit library! And back then if you wanted to write a test for expecting an exception is thrown, you write it like this:


class ExampleTest extends TestCase
{
    /**
     * @expectedException RuntimeException
     */
    public function testExampleObjectThrowsErrorOnMissingCallToSetProperty()
    {
        $testItem = new ExampleObject();
        $testItem->getProperty();
    }
}

But since I'm fresh from college I decided that it was better not to do it, because the docblock is not only 'magical' how it works, it could also throw an assertion failed if the constructing of the object fails, while you actually wanted to test if the exception is thrown after the constructing of the object. You could also not use it in combination with data providers by expected different exception classes in different testcases. So I would write my test like this:


class ExampleTest extends TestCase
{
    public function testExampleObjectThrowsErrorOnMissingCallToSetProperty()
    {
        $testItem = new ExampleObject();
        $this->setExpectedException(\RuntimeException::class);
        $testItem->getProperty();
    }
}

To be honest, it's also a personality trait not to listen and follow my own instincts what works and what does not, but years later I stumbled upon a blog article where a tutor met a student who was just as stubborn as me and made the same conclusion: using @expectedException annotations is terrible!

I tried to find the blog article, but the article is no longer available. I did find a mention on a closed github issue to this blog article and I could get it back with the wayback machine. I felt happy that I had foresight skills as a total n00b, since the expectException annotation became deprecated and was removed from Phpunit.

But it also confirms that even experienced people are still people that could have a specific thoughts/solutions that are flawed or subjective and you could challenge the statement or find trade-offs to their thought/solution. Your lead developer is also just human.

There are more statements I have seen through the years, that some people follow blindly but are seriously flawed:

  • Our application is very dynamic, so we have to use a SPA and Rest API
  • We build a web application, so we have to apply MVC.
  • To build a web application, you need to that in Symfony/Laravel/Yii/Zend/Code Igniter framework
  • You need one test case for every class.
  • You should not use static methods, because you can not mock them in tests.
  • You should avoid integration tests, because they are slower and harder to maintain.
  • You should use only integration tests, because they are the only useful tests.
  • It's very important that all form validation is client side, because it's very important the user gets instant feedback
  • Javascript is terrible to work with
  • Nobody uses PHP anymore.
  • Laravel facades are awesome, because you can use them everywhere in your code.
  • Laravel facades are terrible, because you can use them everywhere in your code.

Matthias Noback once wrote an article about the struggle he has about developers not using dependency injection, because they think it's bad. To me it's a matter of combining all your past experiences and make a (flawed) conclusion how you should do web development. This is also the case outside web development.

For example: did you see too many services with too many dependencies that also have too many dependencies in your constructor? Good chance you prefer singletons/Laravel facades over dependency injection and using integration tests over unit tests.

Now years have passed and I'm the experienced developer. I'm quite aware that my point of view is created from past experiences. Probably I would have become a very different developer if I would have started in Laravel and not started in Symfony at the start of the career.

Recently I also ran into a 'flawed' conclusion I developed over the year. I made the assumption that you should run your integration tests in the 'test' environment with debugging enabled, because your don't want to run into cache issues or make accidental dependencies in order of executing the tests. But this is seriously flawed as running it in production mode is closer to the actual application in production and also your tests will be much faster. So the correct solution would be 'it depends what you test'. In fact I accidentally came up with it because it was mentioned in the documentation of Symfony about writing integration tests.

So what can we conclude here? Many of those flawed conclusions should be a 'it depends' and not a fact. Are you a junior developer? Remember that your team lead might actually have become blind for the downsides of certain solutions and challenge his findings. It would make you a better developer in the long run. And if they don't appreciate constructive criticism: then please find an other job where developers do care about getting better.

For more experienced developers, you should look at yourself if you have also developed personal conclusions that are not facts and wonder if what you learned are still correct assumptions. Do take time to listen to a junior developer criticism. In my experience a better project is one where you do not need to get an explanation first how the application works and a junior developer is a perfect example to test if you have not been over-engineering.

Comments