How to do it...

In order to use Python's built-in unit testing framework, we have to import the Python unittest module. Let's create a new module and name it UnitTests.py.

We first import the unittest module, then we create our own class and, within this class, we inherit and extend the unittest.TestCase class.

The simplest code to do it looks as follows:

import unittest 

class GuiUnitTests(unittest.TestCase):
pass

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

The code isn't doing much yet, but when we run it, we do not get any errors, which is a good sign:

UnitTestsMinimum.py

We actually do get an output written to the console stating that we successfully ran zero tests…

That output is a bit misleading, as all we have done so far is create a class that contains no actual testing methods.

We add testing methods that do the actual unit testing by following the default naming for all the test methods to start with the word test. This is an option that can be changed, but it is much easier and clearer to follow this naming convention.

Let's add a test method that will test the title of our GUI. This will verify that, by passing the expected arguments, we get the expected result:

import unittest 
from Ch08_Code.LanguageResources import I18N

class GuiUnitTests(unittest.TestCase):

def test_TitleIsEnglish(self):
i18n = I18N('en')
self.assertEqual(i18n.title, "Python Graphical User Interface")

We are importing our I18N class from our Resources.py module, passing English as the language to be displayed in our GUI. As this is our first unit test, we will print out the Title result as well, just to make sure we know what we are getting back. We next use the unittest assertEqual method to verify that our title is correct.

Running this code gives us an OK, which means that the unit test passed:

UnitTests_One.py

The unit test runs and succeeds, which is indicated by one dot and the word OK. If it had failed or got an error, we would not have got the dot but an F or E as the output.

We can now do the same automated unit testing check by verifying the title for the German version of our GUI. We simply copy, paste, and modify our code:

import unittest 
from Ch08_Code.LanguageResources import I18N

class GuiUnitTests(unittest.TestCase):

def test_TitleIsEnglish(self):
i18n = I18N('en')
self.assertEqual(i18n.title, "Python Graphical User Interface")

def test_TitleIsGerman(self):
i18n = I18N('en')
self.assertEqual(i18n.title,
'Python Grafische Benutzeroberfl' + "u00E4" + 'che')

Now, we test our internationalized GUI title in two languages and get the following result on running the code:

We ran two unit tests but, instead of an OK, we got a failure. What happened?

Our assertion failed for the German version of our GUI…

While debugging our code, it turns out that in the copy, paste, and modify approach of our unit test code, we forgot to pass German as the language. We can easily fix this:

    def test_TitleIsGerman(self): 
# i18n = I18N('en') # <= Bug in Unit Test
i18n = I18N('de')
self.assertEqual(i18n.title,
'Python Grafische Benutzeroberfl' + "u00E4" + 'che')

When we rerun our unit tests, we get the expected result of all our tests passing:

UnitTestsFail.py with failure corrected

Unit testing code is code and can have bugs too.

While the purpose of writing unit tests is really to test our application code, we have to make sure that our tests are written correctly. One approach from the Test-Driven-Development (TDD) methodology might help us.

In TDD, we develop the unit tests before we actually write the application code. Now, if a test passes for a method that does not even exist, something is wrong. The next step is to create the non-existing method and make sure it will fail. After that, we can write the minimum amount of code necessary to make the unit test pass.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.58.220.83