Commit 2a0c45f5 authored by Franck Thollard's avatar Franck Thollard
Browse files

removing unittest, using assert

parent d3201417
Pipeline #33143 passed with stage
in 1 minute and 1 second
%% Cell type:markdown id: tags:
# Python training UGA 2017
**A training to acquire strong basis in Python to use it efficiently**
Pierre Augier (LEGI), Cyrille Bonamy (LEGI), Eric Maldonado (Irstea), Franck Thollard (ISTerre), Christophe Picard (LJK), Loïc Huder (ISTerre)
# Testing
Why testing ? When testing ? What testing ? How testing ?
%% Cell type:markdown id: tags:
## Why testing (1/4) ?
Coding without testing is dangerous (anyway, you will test somehow):
https://lesjoiesducode.fr/quand-le-client-veut-une-mise-en-prod-avant-de-boucler-ses-tests
https://lesjoiesducode.fr/quand-je-dploie-en-prod-sans-tester
%% Cell type:markdown id: tags:
## Why testing (2/4) ?
Your get more confident with your code:
https://lesjoiesducode.fr/quand-jai-blinde-mes-tests-et-que-les-recetteurs-commencent-a-passer-sur-mes-devs
https://thecodinglove.com/when-i-run-my-code-for-the-first-time-and-i-didnt-test-anything
%% Cell type:markdown id: tags:
## Why testing (3/4) ?
To get sure I conform with the specs, and/or define correct specs:
To get sure I conform with the specs, and/or define correct specs.
Important when something went wrong ...
https://thecodinglove.com/solid-code-wrong-specs
ease parallel dev. and code integration.
Ease parallel dev. and code integration.
%% Cell type:markdown id: tags:
## Why testing (4/4) ?
To check **non regression**:
- when there is a refactor
- when there is a critical code evolution
- when it crashes, to select where to look for the pb
%% Cell type:markdown id: tags:
## When testing ?
Historically, we use to test **after coding**
1) I code
2) I test
3) Go to 1)
%% Cell type:markdown id: tags:
## When testing ?
TDD: test driven dev: write the test **before coding**
1) Define the spec
2) Write the test
3) code
4) test
5) if test not pass either go to 1), go to 2) or go to 3)
If enough ressources, the person who write the test and the one who code are different, ... but they consider the same specs!
%% Cell type:markdown id: tags:
### Testing what ?
- Unit tests
- Functionnal tests
%% Cell type:markdown id: tags:
### Testing what ?
**Unit tests**: test functions conforms with the specs, *i.e.* with the "paper" analysis !
%% Cell type:code id: tags:
``` python
def add(a, b):
""" add a and b and return a+b"""
pass
```
%% Cell type:markdown id: tags:
Lets write the function: easy enought !
%% Cell type:code id: tags:
``` python
def add(a, b):
""" add a and b and return a+b"""
return a+b
```
%% Cell type:markdown id: tags:
Let's write the test:
- What do we do if **a and b are not of the same type** ?
- What if a or b (or a and b) are **None** ?
- What if a + b does not exists ? what should happens ?
- What if a or b is **NaN** ?
All these questions has to be answered in order to write the test ... thus to write the function !
%% Cell type:markdown id: tags:
### Testing what ?
**Functional test:** check that the code works when assembling different functions, *i.e.* the functions
can work together !
%% Cell type:markdown id: tags:
<img src="images/unitaire_ok_fonctionnel_ko.jpeg">
<img src="images/topito_banc.jpg">
Soure Topito
%% Cell type:markdown id: tags:
### How to test ?
Different possibilities
- just use assert !
Not detailed here:
- use unittest from the standard lib
- use pytest (rather standard, but need to be installed)
- ....
%% Cell type:markdown id: tags:
### Assert ?
assert test a condition and "crashes" if the condition does not evaluate to True
%% Cell type:code id: tags:
``` python
assert 13 == 10+3
assert type(10) is int
```
%% Cell type:code id: tags:
``` python
assert True is False
```
%% Output
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-10-bf474889e709> in <module>
----> 1 assert True is False
AssertionError:
%% Cell type:code id: tags:
``` python
import unittest
def add(arg0, arg1):
"""Print and return the sum of the two arguments (duck typing).
assuming arg0 + arg1 is well defined.
"""
result = arg0 + arg1
return result
def test_add():
""" test add is ok with int and strings"""
print("testing add with int ", end="")
assert add(1, 2) == 3
print(" .... OK")
print("testing add ok with str", end="")
assert add("a", "b") == "ab"
print("... OK")
print("test add ok")
class TestMyStuff(unittest.TestCase):
def test_add(self):
""" test add """
self.assertEqual(8, add(3, 5))
self.assertEqual("aabb", add("aa", "bb"))
# self.assertEqual(None, add(None, None))
_res = unittest.TextTestRunner(verbosity=2).run(unittest.TestLoader().loadTestsFromTestCase(TestMyStuff))
test_add()
```
%% Output
test_add (__main__.TestMyStuff)
test add ... ok
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK
testing add with int .... OK
testing add ok with str... OK
test add ok
%% Cell type:code id: tags:
``` python
add(2, 3)
```
%% Output
result = 5
5
%% Cell type:code id: tags:
``` python
add('a', 'b')
```
%% Output
result = ab
'ab'
%% Cell type:markdown id: tags:
### Do it yourself: simple function definition
Write a function that returns the sum of the first argument with twice the second argument.
%% Cell type:code id: tags:
``` python
import unittest
def add_second_twice(arg0, arg1):
"""Return the sum of the first argument with twice the second one.
Arguments should be of type that support sum and product by
an integer (e.g. numerical, string, list, ...)
:param arg0: first argument
:param arg1: second argument
:return: arg0 + 2 * arg1
"""
pass
class TestMyStuff0(unittest.TestCase):
def test_add_second_twice(self):
""" test add_second_twice"""
self.assertEqual(13, add_second_twice(3, 5))
self.assertEqual("aabbbb", add_second_twice("aa", "bb"))
self.assertListEqual([1, 2, 3, 4, 3, 4], add_second_twice([1, 2], [3, 4]))
def test_add_second_twice():
""" test add second twice"""
print("testing add second twice with int ", end="")
assert add_second_twice(3, 5) == 13
print("...OK")
print("testing add second twice with strings ", end="")
assert add_second_twice("aa", "bb") == "aabbbb"
print("...OK")
print("testing add second twice with list ", end="")
assert add_second_twice([1,2], [3,4]) == [1, 2, 3, 4, 3, 4]
print("...OK")
print("test add second twice OK with int, string and list")
_res = unittest.TextTestRunner(verbosity=2).run(unittest.TestLoader().loadTestsFromTestCase(TestMyStuff0))
test_add_second_twice()
```
%% Output
test_add_second_twice (__main__.TestMyStuff0)
test add_second_twice ... FAIL
======================================================================
FAIL: test_add_second_twice (__main__.TestMyStuff0)
test add_second_twice
----------------------------------------------------------------------
Traceback (most recent call last):
File "<ipython-input-3-1ec00cf044ac>", line 17, in test_add_second_twice
self.assertEqual(13, add_second_twice(3, 5))
AssertionError: 13 != None
----------------------------------------------------------------------
Ran 1 test in 0.006s
FAILED (failures=1)
testing add second twice with int
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-5-84287d31dec0> in <module>
25 print("test add second twice OK with int, string and list")
26
---> 27 test_add_second_twice()
<ipython-input-5-84287d31dec0> in test_add_second_twice()
15 """ test add second twice"""
16 print("testing add second twice with int ", end="")
---> 17 assert add_second_twice(3, 5) == 13
18 print("...OK")
19 print("testing add second twice with strings ", end="")
AssertionError:
%% Cell type:markdown id: tags:
### Do it yourself: simple function definition
**A solution:**
%% Cell type:code id: tags:
``` python
import unittest
def add_second_twice(arg0, arg1):
"""Return the sum of the first argument with twice the second one.
Arguments should be of type that support sum and product by
an integer (e.g. numerical, string, list, ...)
:param arg0: first argument
:param arg1: second argument
:return: arg0 + 2 * arg1
"""
result = arg0 + 2*arg1
print(f'arg0 + 2*arg1 = {arg0} + 2*{arg1} = {result}')
return result
def test_add_second_twice():
""" test add second twice"""
print("testing add second twice with int ", end="")
assert add_second_twice(3, 5) == 13
print("...OK")
print("testing add second twice with strings ", end="")
assert add_second_twice("aa", "bb") == "aabbbb"
print("...OK")
print("testing add second twice with list ", end="")
assert add_second_twice([1,2], [3,4]) == [1, 2, 3, 4, 3, 4]
print("...OK")
print("test add second twice OK with int, string and list")
class TestMyStuff0(unittest.TestCase):
def test_add_second_twice(self):
""" test add_second_twice"""
self.assertEqual(13, add_second_twice(3, 5))
self.assertEqual("aabbbb", add_second_twice("aa", "bb"))
self.assertListEqual([1, 2, 3, 4, 3, 4], add_second_twice([1, 2], [3, 4]))
_res = unittest.TextTestRunner(verbosity=2).run(unittest.TestLoader().loadTestsFromTestCase(TestMyStuff0))
test_add_second_twice()
```
%% Output
test_add_second_twice (__main__.TestMyStuff0)
test add_second_twice ...
arg0 + 2*arg1 = 3 + 2*5 = 13
arg0 + 2*arg1 = aa + 2*bb = aabbbb
arg0 + 2*arg1 = [1, 2] + 2*[3, 4] = [1, 2, 3, 4, 3, 4]
ok
----------------------------------------------------------------------
Ran 1 test in 0.003s
OK
testing add second twice with int arg0 + 2*arg1 = 3 + 2*5 = 13
...OK
testing add second twice with strings arg0 + 2*arg1 = aa + 2*bb = aabbbb
...OK
testing add second twice with list arg0 + 2*arg1 = [1, 2] + 2*[3, 4] = [1, 2, 3, 4, 3, 4]
...OK
test add second twice OK with int, string and list
%% Cell type:code id: tags:
``` python
myfunc('a', 'b')
```
%% Output
arg0 + 2*arg1 = a + 2*b = abb
'abb'
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment