Juha-Matti Santala
Community Builder. Dreamer. Adventurer.

Testing lifehack: testlab repositories

I want to write better code (and code that in fact works) and writing unit tests helps me a bit in that. However, I'm not very good at setting up testing environments in existing projects. I have worked on some older legacy codebases where to test an individual part of code would have required a complex database and a lot of mocked data because of how the code was written originally.

One time I was working on a project like this, I still wanted to make sure that the functions I wrote were doing the right thing so I set up a new repository on my development machine called php-testlab. There, I set up a system where I would feel comfortable writing unit tests and knew how to run them with a single command.

Whenever I needed to work on fixing a bug or writing new functionality related to a specific part of that codebase, I would use TDD process to build that functionality inside my testlab repository and once I was reasonably certain it worked, I would copy it over to the actual codebase.

It wasn't the best way as those tests didn't end up in the project but at least the new code was tested during development and it increased the quality of the code I produced. Some time passed and I ran into continuing development of another legacy project. Now I had everything already set up with my testlab repository and I was able to start continuing the same thing.

Later, I did a similar thing for Python called python-testlab (innovative naming, I know!) where I had a setup for writing and running unit tests in Python.

Would I recommend others to follow this way? Kinda yes. It's not a real solution to the problem. Writing those tests into the project is. But sometimes life is messy and if you're able to increase your confidence in your code and reduce the anxiety of writing that code, I call that a win.

My PHP-testlab setup

My php-testlab has a couple of files:

composer.json

{
    "autoload": {
      "classmap": [
        "src/"
      ]
    },
    "require-dev": {
      "phpunit/phpunit": "^7"
    },
    "scripts": {
      "test": "./vendor/bin/phpunit"
    }
}

And then in tests/ folder I have file for each functionality as a separate test suite.

<?php

use PHPUnit\Framework\TestCase;

class HelloWorldTests extends TestCase {
  function test_hello_world() {
    $expected = 'Hello world';
    $result = greetings('world');
    $this->assertEquals($result, $expected);
  }
}

Now I can run my test with composer test tests/HelloWorldTests.

My python-testlab setup

For Python, I have setup a virtualenv environment so that I can manage packages when needed. After that, I have test files in the root like this:

test_string_methods.py

import unittest

class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')

    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('Foo'.isupper())

    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.assertRaises(TypeError):
            s.split(2)

if __name__ == '__main__':
    unittest.main()

Now I can run these with python -m unittest test_string_methods.py.

Syntax Error

Sign up for Syntax Error, a monthly newsletter that helps developers turn a stressful debugging situation into a joyful exploration.