Don’t repeat the logic in the unit tests

There are multiple mistakes you can do, as software engineer, when you define and write the unit tests for your software.

One of the most common I saw it was to repeat the logic from the tested function/method in the unit test function

### contants.py
HARD_UPPER = 10
SOFT_LOWER = 5
INTERMEDIATE_VALUES = [5, 6, 7, 8, 9, 10]

### functions.py
from constants import HARD_UPPER, SOFT_LOWER, INTERMEDIATE_VALUES

def my_func(x):
	if x in INTERMEDIATE_VALUES:
		return x + 1

	if x > HARD_UPPER:
		return x + x

	if x < SOFT_LOWER:
		return x ** x

Let’s imagine we want to test this dummy function, my_func and we would do it in this way:

from functions import my_func

def test_myfunc():
    test_values = [4, 7, 8, 10]
    for x in test_values:
        if x in [5, 6, 7, 8, 9, 10]:
            expected = x + 1
        if x > 10:
            expected = x + x
        if x < 5:
            expected = x ** x

        assert expected == my_func(x)

It looks nice. It tests the boundaries, it seems to test all the intervals. But, let’s imagine someone is going into constans.py and does this change, increases the SOFT_LOWER with 1 and removes 5 from INTERMEDIATE_VALUES.

SOFT_LOWER = 6
INTERMEDIATE_VALUES = [6, 7, 8, 9, 10]

If we run our tests, everything is green, but some results are not the expected ones, for example, my_func(5), before 5 was in INTERMEDIATE_VALUES and the result was 6. Now, 5 is under the condition if x < 5 so, the result is 5 ^ 5 = 3125.

Ofcourse, abose it is just a silly example where I tried to copy/paste the logic from the target function to the test and the easier fix would be just to try to hardcode the boundaries and some itermediate values, like:

def test_myfunc():
    assert my_func(4) == 256
    assert my_func(5) == 6
    assert my_func(10) == 11
    assert my_func(11) == 22
    assert my_func(8) == 9

Now, we can see the test is failing for x=5

>       assert my_func(5) == 6
E       assert 3125 == 6
E        +  where 3125 = my_func(5)

This is the case when the border values really matters and we want to be sure the developer is councious of this change (they will see the tests failing). This such case can be for example the tax applied (we don’t want to change the VAT value for a country too often, right?) or the maximum number of connected devices (eg: Netflix).

If we can argue the values are not so sensitive we could import directly the constants and use them instead of hardcoding in the test (eg: the time when the weekely report email is sent to the team’s PM and someone change it by mistake from 5PM to 5AM).

Why there are so many wrong strategies?

Because we try to avoid the hard work necessary to create a good strategy it is the main reason why there are so many cases of bad strategies.

The reason why we avoid to work on a better strategy is the difficulty to take decisions. A bad strategy is, in many situations, the consequence of the incapacity of the leaders to take a decision at the right moment.

More in Good Strategy Bad Strategy: The Difference and Why It Matters

How to win friends and influence people in 10 steps

We can say the best books are the ones which pass the test of time. How to win friends and influence people was published in 1936 but it’s more actual than ever.

1. DO NOT CRITICIZE

Try to understand the people, instead of stop them to talk. It is much more useful than to criticize.

Try to imagine why they are doing what they are doing and ask them questions. It is better than judge them.

2. SHOWS HONEST APPRECIATION

Anyone can be better than me in some fields. In this sense, I can learn from them. Try to think to the best qualities of the other person, without going to extreme adulation. Be generous in praise.

3. BE SINCERELY INTERESTED IN OTHERS

To have real friends, help others and appreciate them. You must be interested in the other’s life: ask how they are doing, what they like, and anything else that might be important to them.

To be interesting, you have to be interested.

4. BE A GOOD LISTENER

If you aspire to have a good conversation, you first have to know how to listen.

Encourages the other to talk about him/her.

5. SPEAK ABOUT WHAT THE OTHERS ARE INTERESTED

Speak about what the other person is interested is beneficial for both parts. Make sure you know what concerns and interests they have and focus on bringing them up often in the conversation.

6. MAKE THEM FEEL IMPORTANT

Speak to the people about them and they will listen you for hours, but… you must talk in a sincere manner.

7. RESPECT THE OPINIONS OF OTHERS

NEVER tell to a person he/she is wrong. You will put them in a defensive position. You have to act with tact. Before argue with someone, you can say “maybe I am wrong” or “I am many times wrong”.

8. ADMIT YOUR MISTAKES

If you are wrong, admit quickly and clearly. To criticize yourself when you are wrong is more funny and gives better results than defending yourself.

9. TALK ABOUT YOUR MISTAKES FIRST

Before correcting someone, a true lider speaks first about their own errors. This can help the other one to improve their behaviour.

10. PRAISE PROGRESS

The qualities of a person dries under criticism but they develop under stimulation. Praise others and inspire them to develop their full potential.

Backup database in S3

A simple cron backup script of the databse in aws s3. Our script is called mysqlbackup.sh and it looks like this:

#!/bin/bash
DB="razvantudorica"
NOW=$(date +"%m_%d_%Y")
BACKUPFILE="${DB}_${NOW}.sql.gz"
mysqldump --login-path=s3gallery --databases $DB | gzip > $BACKUPFILE
aws s3 cp $BACKUPFILE s3://backup.razvantudorica.net/$BACKUPFILE --profile backuper
rm $BACKUPFILE

And now a few explanations about the script.

First of all we need to have installed the awscli command.

Afterwords, as you can see, the database password is not hardcoded into the script. We can setup the password with mysql_config_editor. This will store authentication credentials in an encrypted login file named .mylogin.cnf.

For our example database, razvantudorica, and database user myuser, we can run

mysql_config_editor set --login-path=razvantudorica --host=localhost --user=myuser --password

The next step is to configure aws s3 bucket and credentials.

  • Create a bucket in s3, in our example is called backup.razvantudorica.net.
  • Create the IAM credentials and save them in ~/.aws/credentials as
[backuper]
aws_access_key_id=AK... 
aws_secret_access_key=...
  • And in ~/.aws/config add
[profile backuper]
region=eu-west-1
output=json
  • The last step is to test our script. If no error occurs at running and the backup file is uploaded successfully in S3, then everything is correct and we can add it the crontab list.
  • Run crontab -e and add this line
0  1 * * * /root/mysqlbackup.sh >> /var/log/mysqlbackup.log