Skip to content

Commit 33b6fc1

Browse files
committed
Add test_docs folder and test_mock_patch and test_pytest_ini
1 parent 3906c28 commit 33b6fc1

8 files changed

Lines changed: 286 additions & 108 deletions

File tree

‎.idea/Mission.iml‎

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎questionnaire.py‎

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,26 +57,24 @@ def FromJSON(json_question):
5757
for i in range (0, len(json_question['choix'])):
5858
choice.append(json_question['choix'][i][0])
5959
if json_question['choix'][i][1]==True :
60-
# Enregistre le numero de la bonne reponse
61-
# is_answer = json_question['choix'][i][0]
62-
is_answer = i
60+
is_answer = i+1
6361
return Question(json_question['titre'], choice, is_answer)
6462

6563
def ask(self, index):
6664
print(f"QUESTION {index}")
6765
print(" " + self.title)
6866
for i in range(len(self.choice)):
69-
print(" ", i+1, "-", self.choice[i]+"\n")
67+
print(" ", i+1, "-", self.choice[i])
7068

71-
if Question.request_choice_to_user(1, len(self.choix)) == self.is_answer:
69+
if Question.request_choice_to_user(1, len(self.choice)) == self.is_answer:
7270
print("Bonne réponse\n")
7371
return True
7472
else:
7573
print("Mauvaise réponse\n")
7674
return False
7775

7876
def request_choice_to_user(min, max):
79-
str_answer = input("Votre réponse (entre " + str(min) + " et " + str(max) + ") :")
77+
str_answer = input("Votre réponse (entre " + str(min) + " et " + str(max) + ") : ")
8078
try:
8179
int_answer = int(str_answer)
8280
if min <= int_answer <= max:
@@ -123,7 +121,7 @@ class Questionnaire:
123121
def __init__(self, json_questionnaire):
124122
'''Test the expected json schema before to initiate'''
125123

126-
try
124+
try:
127125
validate(json_questionnaire, self.schema)
128126
except jsonschema.exceptions.ValidationError:
129127
printerr(f"Incompatible Json schema in file : {filename}")
@@ -161,7 +159,7 @@ def load_json_argv( sysargv ):
161159
json_data = None
162160

163161
if len(sysargv)!=2:
164-
printerr (f"Error in argument, should add one .json questionnaire. Example : {ntpath.basename(sys.argv[0])} questionnaire_to_read.json")
162+
printerr (f"Error in argument, should add a single .json questionnaire. Example : {ntpath.basename(sys.argv[0])} questionnaire_to_read.json")
165163
return None
166164

167165
root, extension = os.path.splitext( sysargv[1] )
@@ -175,14 +173,15 @@ def load_json_argv( sysargv ):
175173
try:
176174
response = requests.get(filename)
177175
except:
178-
raise Exception("here")
176+
printerr(f"Invalid URL at : {filename}")
177+
return None
179178
else:
180179
if response.status_code == 404:
181-
printerr(f"Url Not found at : {filename}")
180+
printerr(f"File not found at : {filename}")
182181
return None
183182
else:
184183
try:
185-
json_data = json.loads(response.text)
184+
json_data = json.loads(response.text) # Decode JSON String
186185
except:
187186
printerr(f"Incompatible or no data in JSON file at URL : {filename}")
188187
return None
@@ -197,8 +196,8 @@ def load_json_argv( sysargv ):
197196
return None
198197
else:
199198
with json_file: # Handle the memory needed for the file
200-
try: # Loading of the file as compatible JSON file
201-
json_data = json.load(json_file)
199+
try:
200+
json_data = json.load(json_file) # Read File and Decode JSON String
202201
except json.decoder.JSONDecodeError:
203202
printerr(f"Incompatible or no data in JSON file : {filename}")
204203
return None
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import http.server
2-
import os
2+
import os.path
33
import socketserver
44
import threading
5+
import urllib
56

67
import requests
78

@@ -27,7 +28,10 @@ class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
2728
server_thread.start()
2829
print(f"Server {ip}:{port} loop running in thread {server_thread.name}")
2930

30-
response = requests.get("http://localhost:8000/empty.json")
31+
# get this file via localhost
32+
file_path = urllib.parse.urljoin(f"http://{ip}:{port}/", os.path.basename(__file__))
33+
print("GET : ",file_path)
34+
response = requests.get(file_path)
3135
print(response)
3236

3337
server.shutdown()

‎test_docs/sample_pytest.ini‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[pytest]
2+
python_files=tst_*.py
3+
python_classes=*_tests
4+
python_functions=test test_*

‎test_docs/simple_prog.py‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
class base_API():
3+
4+
def get_data(self):
5+
return 'data1'
6+
7+
class second_API(base_API):
8+
pass
9+
10+
class third_API(base_API):
11+
pass
12+
13+
if __name__ == "__main__":
14+
print( second_API().get_data() )
15+
print( third_API().get_data() )
16+
17+
18+

‎test_docs/test_mock_patch.py‎

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import unittest
2+
from unittest import mock
3+
4+
from simple_prog import second_API, third_API
5+
6+
7+
class Test_API(unittest.TestCase):
8+
9+
# Here is a example of mock.patch used as decorator
10+
@mock.patch('simple_prog.third_API.get_data', return_value="data3")
11+
@mock.patch('simple_prog.second_API.get_data', return_value="data2")
12+
def test_01_mock_patch_decorator(self, represents_closer_patch, represents_farthest_patch):
13+
self.assertEqual(second_API().get_data(), 'data2')
14+
self.assertEqual(third_API().get_data(), 'data3')
15+
16+
# We can do the same using the 'with' statement / No argument needed
17+
def test_02_mock_patch_with_statement(self):
18+
with mock.patch('simple_prog.second_API.get_data', return_value="data2"):
19+
with mock.patch('simple_prog.third_API.get_data', return_value="data3"):
20+
self.assertEqual(second_API().get_data(), 'data2')
21+
self.assertEqual(third_API().get_data(), 'data3')
22+
23+
# Or separatly
24+
def test_03_separate_second_API(self):
25+
with mock.patch('simple_prog.second_API.get_data', return_value="data2"):
26+
self.assertEqual(second_API().get_data(), 'data2')
27+
28+
def test_04_separate_third_API(self):
29+
with mock.patch('simple_prog.third_API.get_data', return_value="data3"):
30+
self.assertEqual(third_API().get_data(), 'data3')
31+
32+
# It is also possible to add setUp and tearDown, respectively executed before or after the test function
33+
def setUp(self) -> None:
34+
self.second_API_patch = mock.patch('simple_prog.second_API.get_data', return_value="data2")
35+
self.third_API_patch = mock.patch('simple_prog.third_API.get_data', return_value="data3")
36+
self.second_API_patch.start()
37+
self.third_API_patch.start()
38+
39+
def test_05_with_setup_teardown(self):
40+
self.assertEqual(second_API().get_data(), 'data2')
41+
self.assertEqual(third_API().get_data(), 'data3')
42+
43+
def tearDown(self) -> None:
44+
self.second_API_patch.stop()
45+
self.third_API_patch.stop()
46+
47+
# A test function can also return different value, depending of the number of calls
48+
def test_06_side_effects(self):
49+
with mock.patch('simple_prog.second_API.get_data', side_effect=["data2", "data3", "data4"]):
50+
# first call should return 'data2'
51+
self.assertEqual(second_API().get_data(), 'data2')
52+
# second call should return 'data3'
53+
self.assertEqual(second_API().get_data(), 'data3')
54+
# third call should return 'data4'
55+
self.assertEqual(second_API().get_data(), 'data4')
56+
57+
# This can also be used for Exception calls
58+
def test_07_mock_patch_exception(self):
59+
with mock.patch('simple_prog.second_API.get_data', side_effect=Exception("Boom!")) as second_API_patch:
60+
# self.assertEqual( second_API().get_data(),'data2') #Return 'Exception: Boom!'
61+
self.assertRaises(Exception, second_API_patch)
62+
63+
# mock.patch can be changed as mock.patch.object to facilitate the reading
64+
def test_08_with_mock_patch_object(self):
65+
with mock.patch.object(second_API, 'get_data', return_value="data2"):
66+
self.assertEqual(second_API().get_data(), 'data2')
67+
68+

0 commit comments

Comments
 (0)