SlideShare a Scribd company logo
1 of 34
Download to read offline
How to fake properly
by
rainer schuettengruber
who am i
• database engineer
• currently keeps Oracle Exadata systems up and running
• uses Python to automate routine tasks
unit tests
• a piece of software that tests parts of your code base
• isolate a unit and validate its correctness
• form the basic pillar of Test-Driven Development
• should be written before actually implementing the intended
functionality
• commonly automated as part of your CI pipeline
• frameworks for all common languages, e.g. JUnit, NUnit, …
• Python comes with pytest
unit tests
test_matlib.py:
from matlib import div
def test_div():
assert div(4,2) == 2
$ pytest -v
collected 0 items / 1 errors
ImportError while importing test module
'/home/debadmin/mock_talk/unit_test/test_matlib.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
test_matlib.py:1: in <module>
from matlib import div
E ModuleNotFoundError: No module named 'matlib'
============================== 1 error in 0.36 seconds ================
unit testsmatlib.py:
def div(dividend, divisor):
if divisor != 0:
result = dividend / divisor
else:
print('not defined')
result = float('NaN')
return result
$ pytest -v
collected 1 item
test_div.py::test_div PASSED [100%]
=== 1 passed in 0.01 seconds =====================================
code coverage
• determines the percentage of code lines executed by a unit test
• should be close to 100%
• reports should be part of your CI pipeline
• provided by the pytest-cov plugin
• nicely integrates with Jenkins’ Cobertura plugin
code coverage
$ pytest --cov -v
collected 1 item
test_matlib.py::test_div PASSED [100%]
----------- coverage: platform linux, python 3.7.2-final-0 -----------
Name Stmts Miss Cover
------------------------------------
matlib.py 6 2 67%
test_matlib.py 4 0 100%
------------------------------------
TOTAL 10 2 80%
========== 1 passed in 0.03 seconds =====
code coverage
def test_div():
assert div(4,2) == 2
def div(dividend, divisor):
1 if divisor != 0:
2 result = dividend / divisor
3 else:
4 print('not defined')
5 result = float('NaN')
6 return result
this code path is not
considered, therefore code
coverage of 67% (4/6)
code coverage
testmatlib.py:
import math
from matlib import div
def test_div():
assert div(4,2) == 2
def test_div_by_zero():
assert math.isnan(div(4,0))
$ pytest --cov -v
collected 2 items
test_matlib.py::test_div PASSED [ 50%]
test_matlib.py::test_div_by_zero PASSED [100%]
----------- coverage: platform linux, python 3.6.6-final-0 -----------
Name Stmts Miss Cover
------------------------------------
matlib.py 6 0 100%
test_matlib.py 6 0 100%
------------------------------------
TOTAL 12 0 100%
branch coverage
def my_partial_fn(x):
if x:
y = 10
return y
def test_my_partial_fn():
assert my_partial_fn(1) == 10
----------- coverage: platform linux, python 3.6.6-final-0 -----------
Name Stmts Miss Cover
-----------------------------------
mylib.py 4 0 100%
test_mylib.py 3 0 100%
-----------------------------------
TOTAL 7 0 100%
code coverage 100%, however, code is bound to fail …
>>> my_partial_fn(0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in my_partial_fn
UnboundLocalError: local variable 'y' referenced before assignment
code coverage
there is room for
improvement
fake tests
def unit_under_test:
.
SendEmail.send_message(msg)
.
class SendEmail:
.
.
def send_message(self, message):
mail_client = smtplib.SMTP(‘localhost’)
mail_client.send_message(message)
mail_client.close()
.
.
• running this in a test suite would spark off unintended mails
• however, seen from a code coverage perspective it would suffice to know
whether SendEmail.send_message has been called
mock
You use mock to describe something which is not real or genuine, but
which is intended to be very similar to the real thing. (Collins
Dictionary)
In object-oriented programming, mock objects are simulated objects
that mimic the behaviour of real objects in controlled ways.
(Wikipedia)
use cases
• avoid undesired effects of API calls
• deal with non deterministic results, e.g. current time
• decrease runtime of your test suite
• deal with states that are difficult to reproduce, e.g. network error
• break dependency chain
• reduce complexity of your unit test setup/teardown
unittest.mock
unittest.mock is a library for testing in Python. It allows you to replace
parts of your system under test with mock objects and make
assertions about how they have been used.
unittest.mock.patch
def get_current_working_path():
path = os.getcwd()
return path
needs to be
replaced within
the scope of the
unit test
@mock.patch('os.getcwd')
unittest.mock.patch
def get_current_working_path():
path = os.getcwd()
return path
@mock.patch('os.getcwd')
def test_call_only(mocked_getcwd):
pytest takes the patch
decorator into consideration
and passes an instance of
MagicMock() to the test
function
unittest.mock.patch
def get_current_working_path():
path = os.getcwd()
return path
@mock.patch('os.getcwd')
def test_call_only(mocked_getcwd):
mocked_getcwd.return_value =
'/home/debadmin/mock_call'
before calling get_current_working_path()
the attribute return_value is set, which is
acutally the fake
unittest.mock.patch
def get_current_working_path():
path = os.getcwd()
return path
@mock.patch('os.getcwd')
def test_call_only(mocked_getcwd):
mocked_getcwd.return_value =
'/home/debadmin/mock_call'
path = get_current_working_path()
since everything is arranged
time to call the unit under test
unittest.mock.patch
def get_current_working_path():
path = MagicMock(
return_value =
'/home/deba..
)
return path
@mock.patch('os.getcwd')
def test_call_only(mocked_getcwd):
mocked_getcwd.return_value =
'/home/debadmin/mock_call'
path = get_current_working_path()
os.getcwd() is replaced by a
MagicMock object
unittest.mock.patch
def get_current_working_path():
path = MagicMock(
return_value =
'/home/deba..
)
return path
@mock.patch('os.getcwd')
def test_call_only(mocked_getcwd):
mocked_getcwd.return_value =
'/home/debadmin/mock_call'
path = get_current_working_path()
the faked path will be
returned to the caller
unittest.mock.patch
def get_current_working_path():
path = MagicMock(
return_value =
'/home/deba..
)
return path
@mock.patch('os.getcwd')
def test_call_only(mocked_getcwd):
mocked_getcwd.return_value =
'/home/debadmin/mock_call'
path = get_current_working_path()
assert path == '/home/debadmin/mock_call'
test condition evaluates to
true
unittest.mock
import os
def get_current_working_path():
path = os.getcwd()
print ('ncurrent directory is : ' + str(path))
return path
if __name__ == '__main__':
current_working_path = get_current_working_path()
debadmin@jenkins1:/tmp/mock_talk>python sample1.py
current directory is : /tmp/mock_talk
debadmin@jenkins1:/tmp/mock_talk>
unittest.mock.patch
>>> from unittest import mock
>>> with mock.patch('os.getcwd') as mocked_getcwd:
... dir(mocked_getcwd)
...
mocking out os.getcwd by
means of an context
manager
possible assertions about
mock object usage
['assert_any_call', 'assert_called', 'assert_called_once',
'assert_called_once_with', 'assert_called_with', 'assert_has_calls',
'assert_not_called', 'attach_mock', 'call_args', 'call_args_list',
'call_count', 'called', 'configure_mock', 'method_calls',
'mock_add_spec', 'mock_calls', 'reset_mock', 'return_value',
'side_effect']
>>>
unittest.mock.patch
debadmin@jenkins1:~/mock_talk$ pytest -v -s -k test_call_only
=========== test session starts =======================================
platform linux -- Python 3.7.2, pytest-4.3.0, py-1.8.0, pluggy-0.9.0 --
/opt/python/bin/python3.7
cachedir: .pytest_cache
rootdir: /home/debadmin/mock_talk, inifile:
collected 1 item
test/test_sample1.py::test_call_only
current directory is : <MagicMock name='getcwd()' id='139723199533968'>
PASSED
========== 1 passed in 0.01 seconds =====================================
os.getcwd has been
replaced by a MagicMock
object
@mock.patch('os.getcwd')
def test_call_only(mocked_getcwd):
path = get_current_working_path()
mocked_getcwd.assert_called_once()
unittest.mock.patch
debadmin@jenkins1:~/mock_talk$ pytest -v -s -k test_return_value
=========== test session starts =======================================
platform linux -- Python 3.7.2, pytest-4.3.0, py-1.8.0, pluggy-0.9.0 --
/opt/python/bin/python3.7
cachedir: .pytest_cache
rootdir: /home/debadmin/mock_talk, inifile:
collected 1 item
test/test_sample1.py::test_return_value
current directory is : /home/debadmin/mock_call
PASSED
========== 1 passed in 0.01 seconds =====================================
@mock.patch('os.getcwd')
def test_call_only(mocked_getcwd):
mocked_getcwd.return_value = '/home/debadmin/mock_call'
path = get_current_working_path()
assert path == '/home/debadmin/mock_call'
faked return value
print considers faked
return value
unittest.mock.patch
@mock.patch('subprocess.check_call')
def test_stop_database(self, mock_check_call):
fb = Flashback(
restore_point_name='TEST1',
oracle_home='/opt/oracle/product/12.1.0.2.180417/db_test',
oracle_sid='TTEST1'
)
fb._stop_database()
mock_check_call.assert_called_with(
['/opt/oracle/product/12.1.0.2.180417/db_test/bin/srvctl',
'stop',
'database',
'-d',
'TTEST_XD0104',
]
def _stop_database(self):
LOG.info('stopping database %s ...', self.db_unique_name)
subprocess.check_call(
[self.srvctl_command, 'stop', 'database', '-d', self.db_unique_name]
)
srvctl deals with stopping
a cluster database, which
is not available for the
test system
testing the srvctl command is
out of scope, however,
determining that is has been
called with appropriate
parameters is of interest
unittest.mock.patch
@mock.patch('rlb.common.oradb.DatabaseLib.sql_plus_task')
def test_run_flashback_restore(self, mock_sql_plus_task):
fb = Flashback(
restore_point_name='TEST1',
oracle_home='/opt/oracle/product/12.1.0.2.180417/db_test',
oracle_sid='TTEST1'
)
fb._run_flashback_restore()
mock_sql_plus_task.assert_any_call(
'nflashback database to restore point TEST1;n'
)
mock_sql_plus_task.assert_any_call(
'alter database open resetlogs;'
)
def _run_flashback_restore(self):
LOG.info('restoring database ... ')
self.dl.sql_plus_task(< restore command >)
self.dl.sql_plus_task('alter database open resetlogs;')
2 calls of sql_plus_task
with different parameters
the restore command
the open database
command
references
• Kent B. (1999). Extreme Programming. Addison-Wesley.
• unittest.mock – mock object library. [online] Available at:
https://docs.python.org/3/library/unittest.mock.html
• What the mock? – A cheatsheet for mocking in Pyhton. [online] Available at:
https://medium.com/@yeraydiazdiaz/what-the-mock-cheatsheet-mocking-in-
python-6a71db997832
questions and answers
speaker unit test
If you liked the talk leave a comment at https://www.pydays.at/feedback
If you didn‘t like the talk leave a comment but be gentle
Thx for your attention and enjoy your lunch

More Related Content

What's hot

Unit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMockUnit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
Robot Media
 
Beginning PHPUnit
Beginning PHPUnitBeginning PHPUnit
Beginning PHPUnit
Jace Ju
 
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
Enterprise PHP Center
 
Unit Testing Presentation
Unit Testing PresentationUnit Testing Presentation
Unit Testing Presentation
nicobn
 
Advanced Java Practical File
Advanced Java Practical FileAdvanced Java Practical File
Advanced Java Practical File
Soumya Behera
 
D Trace Support In My Sql Guide To Solving Reallife Performance Problems
D Trace Support In My Sql Guide To Solving Reallife Performance ProblemsD Trace Support In My Sql Guide To Solving Reallife Performance Problems
D Trace Support In My Sql Guide To Solving Reallife Performance Problems
MySQLConference
 

What's hot (20)

Unit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMockUnit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
 
Beginning PHPUnit
Beginning PHPUnitBeginning PHPUnit
Beginning PHPUnit
 
Stop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScriptStop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScript
 
Unit Testng with PHP Unit - A Step by Step Training
Unit Testng with PHP Unit - A Step by Step TrainingUnit Testng with PHP Unit - A Step by Step Training
Unit Testng with PHP Unit - A Step by Step Training
 
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
 
Unit Testing Presentation
Unit Testing PresentationUnit Testing Presentation
Unit Testing Presentation
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
 
Secret unit testing tools no one ever told you about
Secret unit testing tools no one ever told you aboutSecret unit testing tools no one ever told you about
Secret unit testing tools no one ever told you about
 
Java performance
Java performanceJava performance
Java performance
 
Concurrency Concepts in Java
Concurrency Concepts in JavaConcurrency Concepts in Java
Concurrency Concepts in Java
 
Qualidade levada a sério em Python - Emilio Simoni
Qualidade levada a sério em Python - Emilio SimoniQualidade levada a sério em Python - Emilio Simoni
Qualidade levada a sério em Python - Emilio Simoni
 
Building unit tests correctly
Building unit tests correctlyBuilding unit tests correctly
Building unit tests correctly
 
Java PRACTICAL file
Java PRACTICAL fileJava PRACTICAL file
Java PRACTICAL file
 
Unit testing patterns for concurrent code
Unit testing patterns for concurrent codeUnit testing patterns for concurrent code
Unit testing patterns for concurrent code
 
Smarter Testing With Spock
Smarter Testing With SpockSmarter Testing With Spock
Smarter Testing With Spock
 
Advanced Java Practical File
Advanced Java Practical FileAdvanced Java Practical File
Advanced Java Practical File
 
Spock Framework
Spock FrameworkSpock Framework
Spock Framework
 
Node.js System: The Landing
Node.js System: The LandingNode.js System: The Landing
Node.js System: The Landing
 
D Trace Support In My Sql Guide To Solving Reallife Performance Problems
D Trace Support In My Sql Guide To Solving Reallife Performance ProblemsD Trace Support In My Sql Guide To Solving Reallife Performance Problems
D Trace Support In My Sql Guide To Solving Reallife Performance Problems
 
Spock
SpockSpock
Spock
 

Similar to How to fake_properly

pytest로 파이썬 코드 테스트하기
pytest로 파이썬 코드 테스트하기pytest로 파이썬 코드 테스트하기
pytest로 파이썬 코드 테스트하기
Yeongseon Choe
 
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalksSelenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
Lohika_Odessa_TechTalks
 

Similar to How to fake_properly (20)

Python testing using mock and pytest
Python testing using mock and pytestPython testing using mock and pytest
Python testing using mock and pytest
 
Testing My Patience
Testing My PatienceTesting My Patience
Testing My Patience
 
Automation with Ansible and Containers
Automation with Ansible and ContainersAutomation with Ansible and Containers
Automation with Ansible and Containers
 
Testing in those hard to reach places
Testing in those hard to reach placesTesting in those hard to reach places
Testing in those hard to reach places
 
Python testing
Python  testingPython  testing
Python testing
 
Php Unit With Zend Framework Zendcon09
Php Unit With Zend Framework   Zendcon09Php Unit With Zend Framework   Zendcon09
Php Unit With Zend Framework Zendcon09
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?
 
Тестирование и Django
Тестирование и DjangoТестирование и Django
Тестирование и Django
 
Python mocking intro
Python mocking introPython mocking intro
Python mocking intro
 
Grails unit testing
Grails unit testingGrails unit testing
Grails unit testing
 
Testing in Python: doctest and unittest (Updated)
Testing in Python: doctest and unittest (Updated)Testing in Python: doctest and unittest (Updated)
Testing in Python: doctest and unittest (Updated)
 
Testing in Python: doctest and unittest
Testing in Python: doctest and unittestTesting in Python: doctest and unittest
Testing in Python: doctest and unittest
 
pytest로 파이썬 코드 테스트하기
pytest로 파이썬 코드 테스트하기pytest로 파이썬 코드 테스트하기
pytest로 파이썬 코드 테스트하기
 
Klee and angr
Klee and angrKlee and angr
Klee and angr
 
MT_01_unittest_python.pdf
MT_01_unittest_python.pdfMT_01_unittest_python.pdf
MT_01_unittest_python.pdf
 
Viktor Tsykunov: Azure Machine Learning Service
Viktor Tsykunov: Azure Machine Learning ServiceViktor Tsykunov: Azure Machine Learning Service
Viktor Tsykunov: Azure Machine Learning Service
 
Effective testing with pytest
Effective testing with pytestEffective testing with pytest
Effective testing with pytest
 
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalksSelenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
Selenium with py test by Alexandr Vasyliev for Lohika Odessa Python TechTalks
 
Unit testing
Unit testingUnit testing
Unit testing
 
Test driven development
Test driven developmentTest driven development
Test driven development
 

Recently uploaded

Uncommon Grace The Autobiography of Isaac Folorunso
Uncommon Grace The Autobiography of Isaac FolorunsoUncommon Grace The Autobiography of Isaac Folorunso
Uncommon Grace The Autobiography of Isaac Folorunso
Kayode Fayemi
 
Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
amilabibi1
 
Unlocking Exploration: Self-Motivated Agents Thrive on Memory-Driven Curiosity
Unlocking Exploration: Self-Motivated Agents Thrive on Memory-Driven CuriosityUnlocking Exploration: Self-Motivated Agents Thrive on Memory-Driven Curiosity
Unlocking Exploration: Self-Motivated Agents Thrive on Memory-Driven Curiosity
Hung Le
 
Jual obat aborsi Jakarta 085657271886 Cytote pil telat bulan penggugur kandun...
Jual obat aborsi Jakarta 085657271886 Cytote pil telat bulan penggugur kandun...Jual obat aborsi Jakarta 085657271886 Cytote pil telat bulan penggugur kandun...
Jual obat aborsi Jakarta 085657271886 Cytote pil telat bulan penggugur kandun...
ZurliaSoop
 
Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...
Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...
Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...
David Celestin
 

Recently uploaded (17)

Introduction to Artificial intelligence.
Introduction to Artificial intelligence.Introduction to Artificial intelligence.
Introduction to Artificial intelligence.
 
Report Writing Webinar Training
Report Writing Webinar TrainingReport Writing Webinar Training
Report Writing Webinar Training
 
Uncommon Grace The Autobiography of Isaac Folorunso
Uncommon Grace The Autobiography of Isaac FolorunsoUncommon Grace The Autobiography of Isaac Folorunso
Uncommon Grace The Autobiography of Isaac Folorunso
 
Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
 
Dreaming Music Video Treatment _ Project & Portfolio III
Dreaming Music Video Treatment _ Project & Portfolio IIIDreaming Music Video Treatment _ Project & Portfolio III
Dreaming Music Video Treatment _ Project & Portfolio III
 
Digital collaboration with Microsoft 365 as extension of Drupal
Digital collaboration with Microsoft 365 as extension of DrupalDigital collaboration with Microsoft 365 as extension of Drupal
Digital collaboration with Microsoft 365 as extension of Drupal
 
Zone Chairperson Role and Responsibilities New updated.pptx
Zone Chairperson Role and Responsibilities New updated.pptxZone Chairperson Role and Responsibilities New updated.pptx
Zone Chairperson Role and Responsibilities New updated.pptx
 
Unlocking Exploration: Self-Motivated Agents Thrive on Memory-Driven Curiosity
Unlocking Exploration: Self-Motivated Agents Thrive on Memory-Driven CuriosityUnlocking Exploration: Self-Motivated Agents Thrive on Memory-Driven Curiosity
Unlocking Exploration: Self-Motivated Agents Thrive on Memory-Driven Curiosity
 
Dreaming Marissa Sánchez Music Video Treatment
Dreaming Marissa Sánchez Music Video TreatmentDreaming Marissa Sánchez Music Video Treatment
Dreaming Marissa Sánchez Music Video Treatment
 
Jual obat aborsi Jakarta 085657271886 Cytote pil telat bulan penggugur kandun...
Jual obat aborsi Jakarta 085657271886 Cytote pil telat bulan penggugur kandun...Jual obat aborsi Jakarta 085657271886 Cytote pil telat bulan penggugur kandun...
Jual obat aborsi Jakarta 085657271886 Cytote pil telat bulan penggugur kandun...
 
lONG QUESTION ANSWER PAKISTAN STUDIES10.
lONG QUESTION ANSWER PAKISTAN STUDIES10.lONG QUESTION ANSWER PAKISTAN STUDIES10.
lONG QUESTION ANSWER PAKISTAN STUDIES10.
 
AWS Data Engineer Associate (DEA-C01) Exam Dumps 2024.pdf
AWS Data Engineer Associate (DEA-C01) Exam Dumps 2024.pdfAWS Data Engineer Associate (DEA-C01) Exam Dumps 2024.pdf
AWS Data Engineer Associate (DEA-C01) Exam Dumps 2024.pdf
 
ICT role in 21st century education and it's challenges.pdf
ICT role in 21st century education and it's challenges.pdfICT role in 21st century education and it's challenges.pdf
ICT role in 21st century education and it's challenges.pdf
 
in kuwait௹+918133066128....) @abortion pills for sale in Kuwait City
in kuwait௹+918133066128....) @abortion pills for sale in Kuwait Cityin kuwait௹+918133066128....) @abortion pills for sale in Kuwait City
in kuwait௹+918133066128....) @abortion pills for sale in Kuwait City
 
My Presentation "In Your Hands" by Halle Bailey
My Presentation "In Your Hands" by Halle BaileyMy Presentation "In Your Hands" by Halle Bailey
My Presentation "In Your Hands" by Halle Bailey
 
SOLID WASTE MANAGEMENT SYSTEM OF FENI PAURASHAVA, BANGLADESH.pdf
SOLID WASTE MANAGEMENT SYSTEM OF FENI PAURASHAVA, BANGLADESH.pdfSOLID WASTE MANAGEMENT SYSTEM OF FENI PAURASHAVA, BANGLADESH.pdf
SOLID WASTE MANAGEMENT SYSTEM OF FENI PAURASHAVA, BANGLADESH.pdf
 
Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...
Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...
Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...
 

How to fake_properly

  • 1. How to fake properly by rainer schuettengruber
  • 2.
  • 3.
  • 4. who am i • database engineer • currently keeps Oracle Exadata systems up and running • uses Python to automate routine tasks
  • 5. unit tests • a piece of software that tests parts of your code base • isolate a unit and validate its correctness • form the basic pillar of Test-Driven Development • should be written before actually implementing the intended functionality • commonly automated as part of your CI pipeline • frameworks for all common languages, e.g. JUnit, NUnit, … • Python comes with pytest
  • 6. unit tests test_matlib.py: from matlib import div def test_div(): assert div(4,2) == 2 $ pytest -v collected 0 items / 1 errors ImportError while importing test module '/home/debadmin/mock_talk/unit_test/test_matlib.py'. Hint: make sure your test modules/packages have valid Python names. Traceback: test_matlib.py:1: in <module> from matlib import div E ModuleNotFoundError: No module named 'matlib' ============================== 1 error in 0.36 seconds ================
  • 7. unit testsmatlib.py: def div(dividend, divisor): if divisor != 0: result = dividend / divisor else: print('not defined') result = float('NaN') return result $ pytest -v collected 1 item test_div.py::test_div PASSED [100%] === 1 passed in 0.01 seconds =====================================
  • 8. code coverage • determines the percentage of code lines executed by a unit test • should be close to 100% • reports should be part of your CI pipeline • provided by the pytest-cov plugin • nicely integrates with Jenkins’ Cobertura plugin
  • 9. code coverage $ pytest --cov -v collected 1 item test_matlib.py::test_div PASSED [100%] ----------- coverage: platform linux, python 3.7.2-final-0 ----------- Name Stmts Miss Cover ------------------------------------ matlib.py 6 2 67% test_matlib.py 4 0 100% ------------------------------------ TOTAL 10 2 80% ========== 1 passed in 0.03 seconds =====
  • 10. code coverage def test_div(): assert div(4,2) == 2 def div(dividend, divisor): 1 if divisor != 0: 2 result = dividend / divisor 3 else: 4 print('not defined') 5 result = float('NaN') 6 return result this code path is not considered, therefore code coverage of 67% (4/6)
  • 11. code coverage testmatlib.py: import math from matlib import div def test_div(): assert div(4,2) == 2 def test_div_by_zero(): assert math.isnan(div(4,0)) $ pytest --cov -v collected 2 items test_matlib.py::test_div PASSED [ 50%] test_matlib.py::test_div_by_zero PASSED [100%] ----------- coverage: platform linux, python 3.6.6-final-0 ----------- Name Stmts Miss Cover ------------------------------------ matlib.py 6 0 100% test_matlib.py 6 0 100% ------------------------------------ TOTAL 12 0 100%
  • 12. branch coverage def my_partial_fn(x): if x: y = 10 return y def test_my_partial_fn(): assert my_partial_fn(1) == 10 ----------- coverage: platform linux, python 3.6.6-final-0 ----------- Name Stmts Miss Cover ----------------------------------- mylib.py 4 0 100% test_mylib.py 3 0 100% ----------------------------------- TOTAL 7 0 100% code coverage 100%, however, code is bound to fail … >>> my_partial_fn(0) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 4, in my_partial_fn UnboundLocalError: local variable 'y' referenced before assignment
  • 13. code coverage there is room for improvement
  • 14.
  • 15. fake tests def unit_under_test: . SendEmail.send_message(msg) . class SendEmail: . . def send_message(self, message): mail_client = smtplib.SMTP(‘localhost’) mail_client.send_message(message) mail_client.close() . . • running this in a test suite would spark off unintended mails • however, seen from a code coverage perspective it would suffice to know whether SendEmail.send_message has been called
  • 16. mock You use mock to describe something which is not real or genuine, but which is intended to be very similar to the real thing. (Collins Dictionary) In object-oriented programming, mock objects are simulated objects that mimic the behaviour of real objects in controlled ways. (Wikipedia)
  • 17. use cases • avoid undesired effects of API calls • deal with non deterministic results, e.g. current time • decrease runtime of your test suite • deal with states that are difficult to reproduce, e.g. network error • break dependency chain • reduce complexity of your unit test setup/teardown
  • 18. unittest.mock unittest.mock is a library for testing in Python. It allows you to replace parts of your system under test with mock objects and make assertions about how they have been used.
  • 19. unittest.mock.patch def get_current_working_path(): path = os.getcwd() return path needs to be replaced within the scope of the unit test @mock.patch('os.getcwd')
  • 20. unittest.mock.patch def get_current_working_path(): path = os.getcwd() return path @mock.patch('os.getcwd') def test_call_only(mocked_getcwd): pytest takes the patch decorator into consideration and passes an instance of MagicMock() to the test function
  • 21. unittest.mock.patch def get_current_working_path(): path = os.getcwd() return path @mock.patch('os.getcwd') def test_call_only(mocked_getcwd): mocked_getcwd.return_value = '/home/debadmin/mock_call' before calling get_current_working_path() the attribute return_value is set, which is acutally the fake
  • 22. unittest.mock.patch def get_current_working_path(): path = os.getcwd() return path @mock.patch('os.getcwd') def test_call_only(mocked_getcwd): mocked_getcwd.return_value = '/home/debadmin/mock_call' path = get_current_working_path() since everything is arranged time to call the unit under test
  • 23. unittest.mock.patch def get_current_working_path(): path = MagicMock( return_value = '/home/deba.. ) return path @mock.patch('os.getcwd') def test_call_only(mocked_getcwd): mocked_getcwd.return_value = '/home/debadmin/mock_call' path = get_current_working_path() os.getcwd() is replaced by a MagicMock object
  • 24. unittest.mock.patch def get_current_working_path(): path = MagicMock( return_value = '/home/deba.. ) return path @mock.patch('os.getcwd') def test_call_only(mocked_getcwd): mocked_getcwd.return_value = '/home/debadmin/mock_call' path = get_current_working_path() the faked path will be returned to the caller
  • 25. unittest.mock.patch def get_current_working_path(): path = MagicMock( return_value = '/home/deba.. ) return path @mock.patch('os.getcwd') def test_call_only(mocked_getcwd): mocked_getcwd.return_value = '/home/debadmin/mock_call' path = get_current_working_path() assert path == '/home/debadmin/mock_call' test condition evaluates to true
  • 26. unittest.mock import os def get_current_working_path(): path = os.getcwd() print ('ncurrent directory is : ' + str(path)) return path if __name__ == '__main__': current_working_path = get_current_working_path() debadmin@jenkins1:/tmp/mock_talk>python sample1.py current directory is : /tmp/mock_talk debadmin@jenkins1:/tmp/mock_talk>
  • 27. unittest.mock.patch >>> from unittest import mock >>> with mock.patch('os.getcwd') as mocked_getcwd: ... dir(mocked_getcwd) ... mocking out os.getcwd by means of an context manager possible assertions about mock object usage ['assert_any_call', 'assert_called', 'assert_called_once', 'assert_called_once_with', 'assert_called_with', 'assert_has_calls', 'assert_not_called', 'attach_mock', 'call_args', 'call_args_list', 'call_count', 'called', 'configure_mock', 'method_calls', 'mock_add_spec', 'mock_calls', 'reset_mock', 'return_value', 'side_effect'] >>>
  • 28. unittest.mock.patch debadmin@jenkins1:~/mock_talk$ pytest -v -s -k test_call_only =========== test session starts ======================================= platform linux -- Python 3.7.2, pytest-4.3.0, py-1.8.0, pluggy-0.9.0 -- /opt/python/bin/python3.7 cachedir: .pytest_cache rootdir: /home/debadmin/mock_talk, inifile: collected 1 item test/test_sample1.py::test_call_only current directory is : <MagicMock name='getcwd()' id='139723199533968'> PASSED ========== 1 passed in 0.01 seconds ===================================== os.getcwd has been replaced by a MagicMock object @mock.patch('os.getcwd') def test_call_only(mocked_getcwd): path = get_current_working_path() mocked_getcwd.assert_called_once()
  • 29. unittest.mock.patch debadmin@jenkins1:~/mock_talk$ pytest -v -s -k test_return_value =========== test session starts ======================================= platform linux -- Python 3.7.2, pytest-4.3.0, py-1.8.0, pluggy-0.9.0 -- /opt/python/bin/python3.7 cachedir: .pytest_cache rootdir: /home/debadmin/mock_talk, inifile: collected 1 item test/test_sample1.py::test_return_value current directory is : /home/debadmin/mock_call PASSED ========== 1 passed in 0.01 seconds ===================================== @mock.patch('os.getcwd') def test_call_only(mocked_getcwd): mocked_getcwd.return_value = '/home/debadmin/mock_call' path = get_current_working_path() assert path == '/home/debadmin/mock_call' faked return value print considers faked return value
  • 30. unittest.mock.patch @mock.patch('subprocess.check_call') def test_stop_database(self, mock_check_call): fb = Flashback( restore_point_name='TEST1', oracle_home='/opt/oracle/product/12.1.0.2.180417/db_test', oracle_sid='TTEST1' ) fb._stop_database() mock_check_call.assert_called_with( ['/opt/oracle/product/12.1.0.2.180417/db_test/bin/srvctl', 'stop', 'database', '-d', 'TTEST_XD0104', ] def _stop_database(self): LOG.info('stopping database %s ...', self.db_unique_name) subprocess.check_call( [self.srvctl_command, 'stop', 'database', '-d', self.db_unique_name] ) srvctl deals with stopping a cluster database, which is not available for the test system testing the srvctl command is out of scope, however, determining that is has been called with appropriate parameters is of interest
  • 31. unittest.mock.patch @mock.patch('rlb.common.oradb.DatabaseLib.sql_plus_task') def test_run_flashback_restore(self, mock_sql_plus_task): fb = Flashback( restore_point_name='TEST1', oracle_home='/opt/oracle/product/12.1.0.2.180417/db_test', oracle_sid='TTEST1' ) fb._run_flashback_restore() mock_sql_plus_task.assert_any_call( 'nflashback database to restore point TEST1;n' ) mock_sql_plus_task.assert_any_call( 'alter database open resetlogs;' ) def _run_flashback_restore(self): LOG.info('restoring database ... ') self.dl.sql_plus_task(< restore command >) self.dl.sql_plus_task('alter database open resetlogs;') 2 calls of sql_plus_task with different parameters the restore command the open database command
  • 32. references • Kent B. (1999). Extreme Programming. Addison-Wesley. • unittest.mock – mock object library. [online] Available at: https://docs.python.org/3/library/unittest.mock.html • What the mock? – A cheatsheet for mocking in Pyhton. [online] Available at: https://medium.com/@yeraydiazdiaz/what-the-mock-cheatsheet-mocking-in- python-6a71db997832
  • 34. speaker unit test If you liked the talk leave a comment at https://www.pydays.at/feedback If you didn‘t like the talk leave a comment but be gentle Thx for your attention and enjoy your lunch