In a recent automation work I’ve been asked to take part in, running a single test safely, according to peers, generally follow a three-step process:
- Delete existing feature files:
rm -rf *.feature
- Create updated feature files:
PROJECT_DIRECTORY=../<dir> APP=<app> TEST=automated ruby create_tests.rb, where app is the name of the app you want to test
- Run the desired specific test:
cucumber --tags @<tag>
This means I have to re-run these three steps over and over for every single test I want to review. That can get tiring easily, especially if I have to re-type them repeatedly, or even if I copy-paste. Using the arrow keys in the terminal helps, but sometimes commands can get lost in the history and then it becomes a bit of a hassle to find them.
There should be a way for me to run an automated check I want to review, given just the app name and the test tag. It would be nice if I can run a specific test using a shorter command but still following the same process as provided.
I decided to set aside a little bit of time to write a personal script, and used Makefile because I’ve had experience with that before.
My personal short command for running a test:
make test app=<app> tag=<tag>
And here’s what the script looks like, which runs the known commands step-by-step plus displays some information on what’s currently happening:
Now I won’t have to worry about remembering what commands to type in as well as the sequence of the commands. I can give more focus on actually reviewing the test itself, which is what’s more important.
In an ongoing software development project we are using Makefile tasks to make running long and repetitive commands as easy and as fun as possible to run. They’re like bash aliases, shortcuts to performing recurrent jobs we frequently have to do while writing new code or testing applications. For example, we could define a task that runs unit tests and code standard checks on an application running in a Docker container like so:
echo "Checking application code with PSR2 standards ..."
docker-compose exec -T php phpcs -v --standard=phpcs.xml ./app/src
echo "Running unit tests ..."
docker-compose exec -T php phpunit --colors=always --configuration ./app
and we would run the task with only the following command:
Cool, right? I don’t have to remember all the exact commands to do what I need to do. And even if I forget the right task name (in this case,
make test) I can just run the
make command in the CLI and I’ll be provided a list of the tasks that I can use for the project.
Now Makefile tasks will run on Unix terminals out of the box. For Windows however, we still have to do some setup before Makefile tasks can run. For my machine at work, I did the following:
- Download and install GnuWin32
- Go to the install folder
C:\Program Files (x86)\GnuWin32\bin
- Copy all files inside the bin folder to the root project directory (
- Add the installation bin directory to the system environment variables
There are other tools that we can use to configure Makefile to run on Windows but this is a quick and easy way to do it. After that we can run
make.exe test on the default cmd CLI but on some Unix-like terminals like the Docker Quickstart Terminal we can definitely use
Problem: I want to automatically run unit tests, lint the application code, and check it’s state against team standards every time I try to commit my changes to a project. It would be nice if the commit aborts if any of the existing tests fails or if I did not follow a particular standard that the team agrees to uphold. The commit pushes through if there are no errors. If possible, I don’t have to change anything in my software development workflow.
Solution: Use a Git pre-commit hook. Under the .git/hooks hidden folder in the project directory, create a new file called pre-commit (without any file extension) containing something like the following bash script (for testing PHP code):
stagedFiles=$(git diff-index --cached HEAD | grep ".php" | grep "^:" | sed 's:.*[DAM][ \\''t]*\([^ \\''t]*\):\1:g');
errorMessage="Please correct the errors above. Commit aborted."
printf "Linting and checking code standards ..."
for file in $stagedFiles
php -l $file
if [[ $LINTVAL != 0 ]]
php core/phpcs.phar --colors --standard=phpcs.xml $file
if [[ $STANDVAL != 0 ]]
printf "Running unit tests ..."
core/vendor/bin/phpunit --colors="always" [TESTS_DIRECTORY]
if [[ $TESTSVAL != 0 ]]
- linting and code standard checks only runs for the files you want to commit changes to
- code standard checks are based on a certain phpcs.xml file
- unit tests inside a particular TESTS_DIRECTORY will run
- the commit will abort whenever any of the lints, code standard checks, or unit tests fails