Skip to content

Commit 41e0ae7

Browse files
committed
added text on unit tests
1 parent e02bb13 commit 41e0ae7

File tree

8 files changed

+353
-21
lines changed

8 files changed

+353
-21
lines changed

bibliography/bibliography.bib

+98-15
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ @string { a_dennison_justing
8484
@string { a_desmaison_alban = "Alban Desmaison" }
8585
@string { a_devin_metthieu = "Matthieu Devin" }
8686
@string { a_devito_zachary = "Zachary {DeVito}" }
87+
@string { a_deza_alfredo = "Alfredo Deza" }
8788
@string { a_dimitrovic_slobodan = "Slobodan Dmitrovi{\'c}" }
8889
@string { a_dubourg_vincent = "Vincent Dubourg" }
8990
@string { a_duchesnay_edouard = "Edouard Duchesnay" }
@@ -109,9 +110,11 @@ @string { a_gatto_laurent
109110
@string { a_gaur_aakanksha = "Aakanksha Gaur" }
110111
@string { a_gerard_marchant_pierre = "Pierre G{\'e}rard{-}Marchant" }
111112
@string { a_ghemawat_sanjay = "Sanjay Ghemawat" }
113+
@string { a_gift_noah = "Noah Gift" }
112114
@string { a_gimelshein_natalia = "Natalia Gimelshein" }
113115
@string { a_gohlke_christoph = "Christoph Gohlke" }
114116
@string { a_gommers_ralf = "Ralf Gommers" }
117+
@string { a_gonzalez_benjamin = "Benjamin Gonzalez" }
115118
@string { a_gramfort_alexandre = "Alexandre Gramfort" }
116119
@string { a_grendell_lina = "Linda Grandell" }
117120
@string { a_grisel_olivier = "Olivier Grisel" }
@@ -163,6 +166,7 @@ @string { a_landau_edmund
163166
@string { a_langa_lukasz = "{\L}ukasz Langa" }
164167
@string { a_larochelle_hugo = "Hugo Larochelle" }
165168
@string { a_larson_eric = "Eric Larson" }
169+
@string { a_laufer_konstantin = "Konstantin L{\"a}ufer" }
166170
@string { a_laxalde_denis = "Denis Laxalde" }
167171
@string { a_leavens_gary_t = "Gary T.\ Leavens" }
168172
@string { a_lee_kent_d = "Kent D.\ Lee" }
@@ -204,6 +208,7 @@ @string { a_niemeyer_patrick
204208
@string { a_niven_ivan = "Ivan Niven" }
205209
@string { a_norvig_peter = "Peter Norvig" }
206210
@string { a_oconnor_john_j = "John J.\ O'Connor" }
211+
@string { a_okken_brian = "Brian Okken" }
207212
@string { a_oliphant_travis_e = "Travis E.\ Oliphant" }
208213
@string { a_pajankar_ashwin = "Ashwin Pajankar" }
209214
@string { a_paquete_luis = "Lu{\'i}s Paquete" }
@@ -237,6 +242,7 @@ @string { a_rodriguez_emily
237242
@string { a_roscoe_timothy = "Timothy Roscoe" }
238243
@string { a_rosenblatt_bill = "Bill Rosenblatt" }
239244
@string { a_roth_ori = "Ori Roth" }
245+
@string { a_runeson_per = "Per Runeson" }
240246
@string { a_russel_stuart = "Stuart J.\ Russell" }
241247
@string { a_ryou_yeonhee = "Yeonhee Ryou" }
242248
@string { a_sachsenberg_timo = "Timo Sachsenberg" }
@@ -268,6 +274,7 @@ @string { a_tejani_alykhan
268274
@string { a_ternent_tobias = "Tobias Ternent" }
269275
@string { a_teukolsky_saul_a = "Saul A.\ Teukolsky" }
270276
@string { a_thirion_bertrand = "Bertrand Thirion" }
277+
@string { a_thiruvthukal_george_k = "George K.\ Thiruvathukal" }
271278
@string { a_tolhurst_denise = "Denise Tolhurst" }
272279
@string { a_torregrossa_dario = "Dario Torregrossa" }
273280
@string { a_torvalds_linus = "Linus Torvalds" }
@@ -297,6 +304,7 @@ @string { a_weckesser_warren
297304
@string { a_weise_thomas = "Thomas Weise" }
298305
@string { a_weiss_ron = "Ron Weiss" }
299306
@string { a_weisstein_eric_w = "Eric Wolfgang Weisstein" }
307+
@string { a_whittaker_james_a = "James A.\ Whittaker" }
300308
@string { a_wicke_martin = "Martin Wicke" }
301309
@string { a_wiebe_mark = "Mark Wiebe" }
302310
@string { a_wieser_eric = "Eric Wieser" }
@@ -356,6 +364,7 @@ @string { l_usa_centennial
356364
@string { l_usa_champaign = "{{Champaign}, {IL}, {USA}}" }
357365
@string { l_usa_cincinnati = "{{Cincinnati}, {OH}, {USA}}" }
358366
@string { l_usa_columbia = "{{Columbia}, {SC}, {USA}}" }
367+
@string { l_usa_flower_mound = "{{Flower Mound}, {TX}, {USA}}" }
359368
@string { l_usa_highland_park = "{{Highland Park}, {NJ}, {USA}}" }
360369
@string { l_usa_hoboken = "{{Hoboken}, {NJ}, {USA}}" }
361370
@string { l_usa_ithaca = "{{Ithaca}, {NY}, {USA}}" }
@@ -420,6 +429,8 @@ @string { p_packt
420429
@string { p_pearson_education = "Pearson Education, Inc." }
421430
@string { p_microsoft_press = "{Microsoft Press}, " # p_pearson_education }
422431
@string { p_plos = "Public Library of Science~{(PLOS)}" }
432+
@string { p_pragmatic_ai_labs = "{Pragmatic {AI} Labs}" }
433+
@string { p_pragmatic_bookshelf = "{{Pragmatic Bookshelf} {by} {The Pragmatic Programmers, {L.L.C.}}}" }
423434
@string { p_princeton_university_press = "Princeton University Press" }
424435
@string { p_python_morsels = "{Python Morsels}" }
425436
@string { p_python_software_foundation = "{\python\ Software Foundation~{(PSF)}}" }
@@ -485,6 +496,8 @@ @string { pa_packt
485496
@string { pa_pearson_education = l_usa_hoboken }
486497
@string { pa_microsoft_press = pa_pearson_education }
487498
@string { pa_plos = l_usa_san_francisco }
499+
@string { pa_pragmatic_ai_labs = l_usa_san_francisco }
500+
@string { pa_pragmatic_bookshelf = l_usa_flower_mound }
488501
@string { pa_princeton_university_press = l_usa_princeton }
489502
@string { pa_python_morsels = l_iceland_reykjavik }
490503
@string { pa_python_software_foundation = l_usa_beaverton }
@@ -549,11 +562,11 @@ @xdata{j_casp
549562
address = pa_typis_academiae
550563
}
551564

552-
@xdata{j_csae,
565+
@xdata{j_cisae,
553566
journal = {Computing in Science \& Engineering},
554-
issn = {1521-9615},
555567
publisher = p_ieee,
556-
address = pa_ieee
568+
address = pa_ieee,
569+
issn = {1521-9615},
557570
}
558571

559572
@xdata{j_hm,
@@ -578,6 +591,13 @@ @xdata{j_ijoc
578591
address = pa_informs
579592
}
580593

594+
@xdata{j_is,
595+
title = {{IEEE}~Software},
596+
publisher = p_ieee,
597+
address = pa_ieee,
598+
issn = {0740-7459},
599+
}
600+
581601
@xdata{j_itose,
582602
journal = {{IEEE} Transactions on Software Engineering},
583603
publisher = p_ieee,
@@ -1007,16 +1027,6 @@ @book{CP2005PNACP
10071027
doi = {10.1007/0-387-28979-8},
10081028
}
10091029

1010-
@book{CR2003LH,
1011-
author = a_oconnor_john_j # and # a_robertson_edmund_f,
1012-
title = {Liu Hui},
1013-
publisher = p_university_of_st_andrews_somas,
1014-
address = pa_university_of_st_andrews_somas,
1015-
date = {2003-12},
1016-
url = {https://mathshistory.st-andrews.ac.uk/Biographies/Liu_Hui},
1017-
urldate = {2024-08-10}
1018-
}
1019-
10201030
@article{D1991TEHOTFF,
10211031
author = a_dutka_jacques,
10221032
title = {The Early History of the Factorial Function},
@@ -1059,6 +1069,15 @@ @book{DBvR2024ITN
10591069
isbn = {9781836208631},
10601070
}
10611071

1072+
@book{DG2020TIP,
1073+
author = a_deza_alfredo # and # a_gift_noah,
1074+
title = {Testing In \python},
1075+
date = {2020-02},
1076+
publisher = p_pragmatic_ai_labs,
1077+
address = pa_pragmatic_ai_labs,
1078+
isbn = {9798616960641},
1079+
}
1080+
10621081
@article{E1737DFCD,
10631082
author = a_euler_leonhard,
10641083
title = {De Fractionibus Continuis Dissertation},
@@ -1202,8 +1221,8 @@ @inbook{H1997IS7FPN
12021221

12031222
@article{H2007MA2GE,
12041223
author = a_hunter_john_d,
1205-
title = {\matplotlib: {A} 2D~Graphics Environment},
1206-
xdata = {j_csae},
1224+
title = {\matplotlib:~{A} 2D~Graphics Environment},
1225+
xdata = {j_cisae},
12071226
volume = {9},
12081227
number = {3},
12091228
pages = {90--95},
@@ -1458,6 +1477,15 @@ @book{NR2005LTBSUSPCB3
14581477
isbn = {978-0-596-00965-6},
14591478
}
14601479

1480+
@book{O2022PTWP,
1481+
author = a_okken_brian,
1482+
title = {\python\ Testing with \pytest},
1483+
date = {2022-02},
1484+
publisher = p_pragmatic_bookshelf,
1485+
address = pa_pragmatic_bookshelf,
1486+
isbn = {9781680508604},
1487+
}
1488+
14611489
@inbook{O2024CD,
14621490
title = {Class Double},
14631491
crossref = {O2024JPSEJDKV2AS},
@@ -1474,6 +1502,16 @@ @book{O2024JPSEJDKV2AS
14741502
urldate = {2024-07-07},
14751503
}
14761504

1505+
@book{OR2003LH,
1506+
author = a_oconnor_john_j # and # a_robertson_edmund_f,
1507+
title = {Liu Hui},
1508+
publisher = p_university_of_st_andrews_somas,
1509+
address = pa_university_of_st_andrews_somas,
1510+
date = {2003-12},
1511+
url = {https://mathshistory.st-andrews.ac.uk/Biographies/Liu_Hui},
1512+
urldate = {2024-08-10}
1513+
}
1514+
14771515
@book{P2021HOMLPAVWP,
14781516
author = a_pajankar_ashwin,
14791517
title = {Hands-on \matplotlib: Learn Plotting and Visualizations with \python~3},
@@ -1483,6 +1521,15 @@ @book{P2021HOMLPAVWP
14831521
isbn = {9781484274101}
14841522
}
14851523

1524+
@book{P2021PUTAAOAEUTIP,
1525+
author = a_pajankar_ashwin,
1526+
title = {\python\ Unit Test Automation: Automate, Organize, and Execute Unit Tests in \python},
1527+
date = {2021-12},
1528+
publisher = p_apress,
1529+
address = pa_apress,
1530+
isbn = {9781484278543},
1531+
}
1532+
14861533
@book{PC2024PL,
14871534
author = a_pylint_contributors,
14881535
title = {\pylint},
@@ -1824,6 +1871,17 @@ @book{R1994PNACMFF
18241871
edition = {2}
18251872
}
18261873

1874+
@article{R2006ASOUTP,
1875+
author = a_runeson_per,
1876+
title = {A Survey of Unit Testing Practices},
1877+
xdata = {j_is},
1878+
volume = {23},
1879+
number = {4},
1880+
pages = {22--29},
1881+
date = {2006-07/2006-08},
1882+
doi = {10.1109/MS.2006.91},
1883+
}
1884+
18271885
@inproceedings{R2023PTHATCPBNI,
18281886
author = a_roth_ori,
18291887
title = {\python\ Type Hints Are Turing Complete (Pearl/Brave New Idea)},
@@ -1976,6 +2034,19 @@ @article{TKY2016BEOEAOTCEG
19762034
urldate = {2024-09-28},
19772035
}
19782036

2037+
@article{TLG2006UTCU,
2038+
author = a_thiruvthukal_george_k # and # a_laufer_konstantin # and # a_gonzalez_benjamin,
2039+
title = {Unit Testing Considered Useful},
2040+
xdata = {j_cisae},
2041+
volume = {8},
2042+
number = {6},
2043+
pages = {76--87},
2044+
date = {2006-11/2006-12},
2045+
doi = {10.1109/MCSE.2006.124},
2046+
url = {https://www.researchgate.net/publication/220094077},
2047+
urldate = {2024-10-01},
2048+
}
2049+
19792050
@techreport{TSSL1995CICSNSE,
19802051
title = {Chinese Internal Code Specification, National Standard Extended~{(GBK)}},
19812052
type = {Technical Supervision Standard Letter},
@@ -2055,6 +2126,18 @@ @inproceedings{VVH2018ELDOSAIOSPACSOTPE
20552126
crossref = {PROC2018ESECFSE},
20562127
}
20572128

2129+
@article{W2000WISTAWIISH,
2130+
author = a_whittaker_james_a,
2131+
title = {What Is Software Testing? And Why Is It So Hard?},
2132+
xdata = {j_is},
2133+
volume = {17},
2134+
number = {1},
2135+
pages = {70--79},
2136+
date = {2000-01/2000/02},
2137+
doi = {10.1109/52.819971},
2138+
addendum = {Practice Tutorial}
2139+
}
2140+
20582141
@book{W2024MAWWR,
20592142
title = {{MathWorld} -- A {Wolfram} Web Resource},
20602143
author = a_weisstein_eric_w,

notation/software.sty

+13-1
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,24 @@ name={Pylint},%
124124
sort={Pylint},%
125125
description={%
126126
is a \pgls{linter} for \python\ that checks for errors, enforces coding standards, and that can make suggestions for improvements~\cite{PC2024PL}. %
127-
Learn more at \url{https://www.pylint.org}.%
127+
Learn more at \url{https://www.pylint.org}, \cref{sec:enumOverSequences}, and in \cref{ut:pylint}.%
128128
}%
129129
}%
130130
\protected\gdef\pylint{\pgls{pylint}}%
131131
%
132132
%
133+
\newglossaryentry{pytest}{%
134+
text={\softwareStyle{pytest}},%
135+
name={pytest},%
136+
sort={pytest},%
137+
description={%
138+
is a framework for writing and executing unit tests in \python~\cite{O2022PTWP,DG2020TIP,P2021PUTAAOAEUTIP}. %
139+
Learn more at \url{https://pytest.org} and in \cref{sec:unitTesting}.%
140+
}%
141+
}%
142+
\protected\gdef\pytest{\pgls{pytest}}%
143+
%
144+
%
133145
\newglossaryentry{python}{%
134146
text={\softwareStyle{Python}},%
135147
name={Python},%

text/back/scripts.tex

+34-2
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,36 @@
99
\gitBash{\programmingWithPythonCodeRepo}{scripts/pylint.sh}{bash:pylint}{%
1010
A \bash\ script for executing \pylint, which prints the command line and the exit code; see \cref{ut:pylint}.}%
1111
%
12+
\gitBash{\programmingWithPythonCodeRepo}{scripts/pytest.sh}{bash:pytest}{%
13+
A \bash\ script for executing test cases with \pytest, which prints the command line and the exit code; see \cref{ut:pytest}.}%
14+
%
1215
Here we provide some scripts that are used within this book.
1316
These scripts are written for the \bash\ shell, which is the default interpreter running in \ubuntu\ \linux\ \pglspl{terminal}.
1417
Therefore, they will not work under \windows\ or other operating systems.
1518
Now, our book focuses on \python\ programming, so \bash\ shell scripts are not in the center of our attention.
1619
We here cannot explain how \bash\ scripts work or what their syntax is.
1720
There exist plenty of books and resources on this interesting topic, such as~\cite{NR2005LTBSUSPCB3,Z2017MB,BN2018BC} or \url{https://www.gnu.org/software/bash/}.
21+
1822
If we would include the scripts in the places where we use them in this book, then this would lead to confusion or tangents in the text which would mess up the flow of the chapters.
1923
Nevertheless, the book would be incomplete if these scripts were not provided at all.
20-
So we put them here, at the end of the book, where they do not hurt anyone and where the interested reader may check them out.%
24+
So we put them here, at the end of the book, where they do not hurt anyone and where the interested reader may check them out.
25+
26+
In the scripts, we install tools if they are not yet installed.
27+
We then apply the tools to whatever the parameters of the scripts state.
28+
Now, in a real environment, a tool can either succeed or fail.
29+
A unit test executed with \pytest\ will fail and exit with a non-zero exit code if the test, well, fails.
30+
A static code analysis tool like \ruff\ will fail with a non-zero exit code if it discovers any issue with the code.
31+
However, our scripts invoking these tools will \emph{not} fail in such cases.
32+
They will collect the exit code of the tool they are invoking and print it.
33+
Then they will exit with exit code~0.
34+
This is necessary for our book building process, which invokes these scripts to construct the outputs of the examples.
35+
If any of them would fail with non-zero exit code, the book building would fail as well.
36+
However, to illustrate that the tools are useful, we must apply them to cases where they would fail.
37+
So for our book, it is necessary that the scripts just print the exit codes while still returning successfully.
38+
For a real productive environment, this is usually not what we want:
39+
We apply the tools to source code precisely to get them to fail on error, because if nothing fails, we know that everything seems to be OK.
40+
In such a practical environment, you would thus not want to use \emph{our} scripts, but you could use the same comments that we use.
41+
Anyway, here is the list of tool scripts.
2142

2243
\Cref{lst:bash:mypy} is a \bash\ script which first checks whether \mypy\ is installed.
2344
If \mypy\ is not installed, it silently installs it.
@@ -40,7 +61,18 @@
4061
\Cref{lst:bash:pylint} offers exactly the same functionality for \pylint.
4162
It checks if this tool is installed and installs it if not.
4263
It then applies \pylint\ to a the selected set of files, using a reasonable default configuration.
43-
\Cref{exec:loops:for_loop_no_enumerate:pylint} is an example for the output of this \pgls{linter}.%
64+
\Cref{exec:loops:for_loop_no_enumerate:pylint} is an example for the output of this \pgls{linter}.
65+
66+
\Cref{lst:bash:pytest} is similarly structured, but instead of performing \emph{static} code analysis, it executes unit test cases.
67+
The directory and list of \python\ files with the test cases are provided as command line arguments.
68+
This script checks if \pytest\ and its plugin \textil{pytest-timeout} are installed and, if not, installs them.
69+
It then executes the tests with a fixed ten second timeout that we use in this book.
70+
Of course, in practical scenarios, you would use a larger timeout, but within the context of this book, ten seconds are enough.
71+
Either way, the script executes the test cases, prints the results as well as potential errors.
72+
Notice that we select some options to make the output less verbose, because for this book, we do want listings that are not too long.
73+
In practical scenarios, you may use different options.
74+
Either way, the script also prints the command that was executed at the beginning and the \pytest\ version used and the program's exit code at the end of the output.
75+
\Cref{exec:functions:test_my_math:pytest,exec:functions:test_my_math_2:pytest,exec:functions:test_my_math_3:pytest} are examples for the output of \pytest.%
4476
%
4577
\endhsection%
4678
%

text/main/basics/simpleDataTypesAndOperations/int/int.tex

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
The draft for the \softwareStyle{C17} standard for the \pgls{C}~programming language lists five signed and five unsigned integer types, plus several ways to extend them~\cite{ISOIEC98892017PLCWDOS}.
1212
The different integer types of both languages have different ranges and sizes, and the programmer must carefully choose which she needs to use in which situation.
1313

14-
\python\ only has one integer type, called \pythonilIdx{int}.
14+
\python~3 only has one integer type, called \pythonilIdx{int}.
1515
This type has basically an unbounded range.
16-
The \python\ interpreter will allocate as much memory as is needed to store the number you want.\footnote{%
16+
The \python~3 interpreter will allocate as much memory as is needed to store the number you want.\footnote{%
1717
Ok, the range is not actually \emph{unbounded}, it is bounded by the amount of memory available on your computer{\dots} {\dots}but for all intents and purposes within this book, we can assume that~$\pythonilIdx{int}\equiv\integerNumbers$.}%
1818
%
1919
\hsection{Integer Arithmetics}%

text/main/basics/variables/assignment/assignment.tex

+1-1
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@
190190
But we can never really write it down.
191191

192192
Well, we I say \inQuotes{we can compute it}, then the question \inQuotes{How?} immediately arises.
193-
One particularly ingenious answer was given by the Chinese mathematician LIU Hui~\cnPdf{liuHui} somewhere in the third century~AD~\cite{CR2003LH} in his commentary to the famous Chinese mathematics book \emph{Jiu Zhang Suanshu}~\cnPdf{jiuZhangSuanShu}~\cite{CR2003LH,SCL1999TNCOTMACAC,S1998LHATFGAOCM,D2010AALHOCAS,C2002LFLHADWTDM}.
193+
One particularly ingenious answer was given by the Chinese mathematician LIU Hui~\cnPdf{liuHui} somewhere in the third century~AD~\cite{OR2003LH} in his commentary to the famous Chinese mathematics book \emph{Jiu Zhang Suanshu}~\cnPdf{jiuZhangSuanShu}~\cite{OR2003LH,SCL1999TNCOTMACAC,S1998LHATFGAOCM,D2010AALHOCAS,C2002LFLHADWTDM}.
194194
In \cref{fig:liuHuiCircle}, we show how~\numberPi, i.e., the ratio of the circumference and the diameter of a circle can be approximated by inscribing regular~$e$\nobreakdash-gons into a circle.
195195
The corners of the $e$\nobreakdash-gons lie on the circle.
196196

0 commit comments

Comments
 (0)