2. Software testing
• Software testing is any activity taken to verify that a given software
system is working as expected
• Types of software testing
• Integration Testing – test how components of a system work together
• System Testing – test the completely integrated system
• Regression testing – test the effects of code changes
• Unit testing – test units of code in isolation
• Security testing – test how data is protected from unauthorized access.
• Acceptance Testing - determine whether a piece of software satisfies all
of the requirements from the business or user's perspective
3. Unit Testing
• Unit Testing is a testing method in which individual units of
code are tested to assert that they are working as expected.
• The goal of unit testing is to isolate each part of the program
and show that the individual parts are correct.
• The functionality of individual functions and classes are
tested on their own.
• Embraced by the open source community.
• unittest module in Python
4. Common concepts
• Test coverage – A measurement of the effectiveness of unit
tests.Test coverage tools instrospect the code when the tests are
running and determines which parts have been executed and
which not. Coverage.py by Ned Batchelder is a common tool in
pyland.
• Test fixtures - A test fixture is a fixed state of a set of objects used
as a baseline for running tests. The purpose of a test fixture is to
ensure that there is a well known and fixed environment in which
tests are run so that results are repeatable. An example is
preparation of input data – can be defined in code, as separate
fixture files(json, yaml etc) or you can use a fixture generating
library such as factoryboy, mixer etc.
5. Mocking
• Mocking is the process of replacing real objects
defined in code with mock/fake objects for the
purposes of unit testing.
• This is achieved by creating objects that emulate
the behavior of real objects.
• The mock objects are used to emulate the
behavior of the real objects that the code under
test depends on.
6. The need for testing
•Find problems early in development
•Deploy with confidence
•Good tests forces good design in code
•Improves software reliabilty.
•Provides a sort of living documentation of
the system.
•Makes integration easier
•Helps in debugging
8. Testing Outcomes
•Success – the code runs as expected
•Failure – code does not work as expected.
•Error – an error either in the code or the
tests which was not anticipated
9. Elements of a good unit test
• Single responsibility
• Does not depend on other tests
• Simple set up
• Readable, preferably by mortals
• DRY does not apply in tests.
10. Hindrances to writing tests
•A waste of time
•Brittle tests
•Slow tests
•My seniors don't see the need.
•Tight timelines
11. Mitigating slow tests
• Keep database access to the minimum, access
only when absolutely necessary
• Replace expensive operations with less expensive
dummy ones, eg hashing algorithms
• Authenticate only where its necessary
• Mock it!
12. 1.2 Mocking
• Mocking is the process of replacing real objects
defined in code with mock/fake objects for the
purposes of unit testing.
• This is achieved by creating objects that emulate
the behavior of real objects.
• The mock objects are used to emulate the
behavior of the real objects that the code under
test depends on.
13. What to mock
•Any interaction with external APIs
•Any unnecessary database calls
•Code that has external side effects, eg
sending mails
•Non trivial object creation
14. The unittest.mock module
• Python 3.3 and later have the mock module inbuilt.
• For python 2, there is need to install the mock module
separately.
• Mocking allows you to replace parts of your system
under test with the mock objects and make assertions
about how they have been used
15. The mock objects
• Mock and MagicMock – When you mock an
object, a Mock or MagicMock class is created
replacing the mocked object. It then will
create all attributes and methods as you
access them and store details of how they
have been used.
• from unittest.mock import Mock, MagicMock
16. How to mock objects
• The most common method is to use the patch object accessible
from the mock module
• from unittest.mock import patch
• The patch object can be used as a decorator or a context manager.
• When the patch object is used as a decorator it will automatically
send a positional argument to the decorated function. The
argument sent is by default a MagicMock class and you can use it
to make assertions about which methods / attributes were used
and arguments they were called with.
19. Setting return values for mocked objects
• The return value attribute on the MagicMock instance
passed into your test function allows you to choose
what the patched callable returns.
20. Using side effects in mocks
• Sometimes you'll want to test that your function correctly handles
an exception, or that multiple calls of the function you're patching
are handled correctly. You can do that using side_effect.
Setting side_effect to an exception raises that exception
immediately when the patched function is called.
• Setting side_effect to an iterable will return the next item from
the iterable each time the patched function is called.
Setting side_effect to any other value will return that value.
• You can also use it in cases where you are testing non-
deterministic values
21. Useful tools and libraries
• Testing libraries: pytest, nose
• Fixture generation: factory_boy, mixer
• Test coverage: coverage.py
• Test automation: tox
• Reference: https://docs.python-guide.org/writing/tests/