\documentclass[11pt]{article}

    \usepackage[breakable]{tcolorbox}
    \usepackage{parskip} % Stop auto-indenting (to mimic markdown behaviour)
    
    \usepackage{iftex}
    \ifPDFTeX
    	\usepackage[T1]{fontenc}
    	\usepackage{mathpazo}
    \else
    	\usepackage{fontspec}
    \fi

    % Basic figure setup, for now with no caption control since it's done
    % automatically by Pandoc (which extracts ![](path) syntax from Markdown).
    \usepackage{graphicx}
    % Maintain compatibility with old templates. Remove in nbconvert 6.0
    \let\Oldincludegraphics\includegraphics
    % Ensure that by default, figures have no caption (until we provide a
    % proper Figure object with a Caption API and a way to capture that
    % in the conversion process - todo).
    \usepackage{caption}
    \DeclareCaptionFormat{nocaption}{}
    \captionsetup{format=nocaption,aboveskip=0pt,belowskip=0pt}

    \usepackage[Export]{adjustbox} % Used to constrain images to a maximum size
    \adjustboxset{max size={0.9\linewidth}{0.9\paperheight}}
    \usepackage{float}
    \floatplacement{figure}{H} % forces figures to be placed at the correct location
    \usepackage{xcolor} % Allow colors to be defined
    \usepackage{enumerate} % Needed for markdown enumerations to work
    \usepackage{geometry} % Used to adjust the document margins
    \usepackage{amsmath} % Equations
    \usepackage{amssymb} % Equations
    \usepackage{textcomp} % defines textquotesingle
    % Hack from http://tex.stackexchange.com/a/47451/13684:
    \AtBeginDocument{%
        \def\PYZsq{\textquotesingle}% Upright quotes in Pygmentized code
    }
    \usepackage{upquote} % Upright quotes for verbatim code
    \usepackage{eurosym} % defines \euro
    \usepackage[mathletters]{ucs} % Extended unicode (utf-8) support
    \usepackage{fancyvrb} % verbatim replacement that allows latex
    \usepackage{grffile} % extends the file name processing of package graphics 
                         % to support a larger range
    \makeatletter % fix for grffile with XeLaTeX
    \def\Gread@@xetex#1{%
      \IfFileExists{"\Gin@base".bb}%
      {\Gread@eps{\Gin@base.bb}}%
      {\Gread@@xetex@aux#1}%
    }
    \makeatother

    % The hyperref package gives us a pdf with properly built
    % internal navigation ('pdf bookmarks' for the table of contents,
    % internal cross-reference links, web links for URLs, etc.)
    \usepackage{hyperref}
    % The default LaTeX title has an obnoxious amount of whitespace. By default,
    % titling removes some of it. It also provides customization options.
    \usepackage{titling}
    \usepackage{longtable} % longtable support required by pandoc >1.10
    \usepackage{booktabs}  % table support for pandoc > 1.12.2
    \usepackage[inline]{enumitem} % IRkernel/repr support (it uses the enumerate* environment)
    \usepackage[normalem]{ulem} % ulem is needed to support strikethroughs (\sout)
                                % normalem makes italics be italics, not underlines
    \usepackage{mathrsfs}
    

    
    % Colors for the hyperref package
    \definecolor{urlcolor}{rgb}{0,.145,.698}
    \definecolor{linkcolor}{rgb}{.71,0.21,0.01}
    \definecolor{citecolor}{rgb}{.12,.54,.11}

    % ANSI colors
    \definecolor{ansi-black}{HTML}{3E424D}
    \definecolor{ansi-black-intense}{HTML}{282C36}
    \definecolor{ansi-red}{HTML}{E75C58}
    \definecolor{ansi-red-intense}{HTML}{B22B31}
    \definecolor{ansi-green}{HTML}{00A250}
    \definecolor{ansi-green-intense}{HTML}{007427}
    \definecolor{ansi-yellow}{HTML}{DDB62B}
    \definecolor{ansi-yellow-intense}{HTML}{B27D12}
    \definecolor{ansi-blue}{HTML}{208FFB}
    \definecolor{ansi-blue-intense}{HTML}{0065CA}
    \definecolor{ansi-magenta}{HTML}{D160C4}
    \definecolor{ansi-magenta-intense}{HTML}{A03196}
    \definecolor{ansi-cyan}{HTML}{60C6C8}
    \definecolor{ansi-cyan-intense}{HTML}{258F8F}
    \definecolor{ansi-white}{HTML}{C5C1B4}
    \definecolor{ansi-white-intense}{HTML}{A1A6B2}
    \definecolor{ansi-default-inverse-fg}{HTML}{FFFFFF}
    \definecolor{ansi-default-inverse-bg}{HTML}{000000}

    % commands and environments needed by pandoc snippets
    % extracted from the output of `pandoc -s`
    \providecommand{\tightlist}{%
      \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
    \DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}}
    % Add ',fontsize=\small' for more characters per line
    \newenvironment{Shaded}{}{}
    \newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{{#1}}}}
    \newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.56,0.13,0.00}{{#1}}}
    \newcommand{\DecValTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}}
    \newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}}
    \newcommand{\FloatTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}}
    \newcommand{\CharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}}
    \newcommand{\StringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}}
    \newcommand{\CommentTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textit{{#1}}}}
    \newcommand{\OtherTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{{#1}}}
    \newcommand{\AlertTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}}
    \newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.02,0.16,0.49}{{#1}}}
    \newcommand{\RegionMarkerTok}[1]{{#1}}
    \newcommand{\ErrorTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}}
    \newcommand{\NormalTok}[1]{{#1}}
    
    % Additional commands for more recent versions of Pandoc
    \newcommand{\ConstantTok}[1]{\textcolor[rgb]{0.53,0.00,0.00}{{#1}}}
    \newcommand{\SpecialCharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}}
    \newcommand{\VerbatimStringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}}
    \newcommand{\SpecialStringTok}[1]{\textcolor[rgb]{0.73,0.40,0.53}{{#1}}}
    \newcommand{\ImportTok}[1]{{#1}}
    \newcommand{\DocumentationTok}[1]{\textcolor[rgb]{0.73,0.13,0.13}{\textit{{#1}}}}
    \newcommand{\AnnotationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}}
    \newcommand{\CommentVarTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}}
    \newcommand{\VariableTok}[1]{\textcolor[rgb]{0.10,0.09,0.49}{{#1}}}
    \newcommand{\ControlFlowTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{{#1}}}}
    \newcommand{\OperatorTok}[1]{\textcolor[rgb]{0.40,0.40,0.40}{{#1}}}
    \newcommand{\BuiltInTok}[1]{{#1}}
    \newcommand{\ExtensionTok}[1]{{#1}}
    \newcommand{\PreprocessorTok}[1]{\textcolor[rgb]{0.74,0.48,0.00}{{#1}}}
    \newcommand{\AttributeTok}[1]{\textcolor[rgb]{0.49,0.56,0.16}{{#1}}}
    \newcommand{\InformationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}}
    \newcommand{\WarningTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}}
    
    
    % Define a nice break command that doesn't care if a line doesn't already
    % exist.
    \def\br{\hspace*{\fill} \\* }
    % Math Jax compatibility definitions
    \def\gt{>}
    \def\lt{<}
    \let\Oldtex\TeX
    \let\Oldlatex\LaTeX
    \renewcommand{\TeX}{\textrm{\Oldtex}}
    \renewcommand{\LaTeX}{\textrm{\Oldlatex}}
    % Document parameters
    % Document title
    \title{Notes on Unit Testing}
    \author{Abridged from Notes by Dr. Burton Ma}
    
    
    
    
    
% Pygments definitions
\makeatletter
\def\PY@reset{\let\PY@it=\relax \let\PY@bf=\relax%
    \let\PY@ul=\relax \let\PY@tc=\relax%
    \let\PY@bc=\relax \let\PY@ff=\relax}
\def\PY@tok#1{\csname PY@tok@#1\endcsname}
\def\PY@toks#1+{\ifx\relax#1\empty\else%
    \PY@tok{#1}\expandafter\PY@toks\fi}
\def\PY@do#1{\PY@bc{\PY@tc{\PY@ul{%
    \PY@it{\PY@bf{\PY@ff{#1}}}}}}}
\def\PY#1#2{\PY@reset\PY@toks#1+\relax+\PY@do{#2}}

\expandafter\def\csname PY@tok@w\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.73,0.73}{##1}}}
\expandafter\def\csname PY@tok@c\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
\expandafter\def\csname PY@tok@cp\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.74,0.48,0.00}{##1}}}
\expandafter\def\csname PY@tok@k\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@kp\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@kt\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.69,0.00,0.25}{##1}}}
\expandafter\def\csname PY@tok@o\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@ow\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.67,0.13,1.00}{##1}}}
\expandafter\def\csname PY@tok@nb\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@nf\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
\expandafter\def\csname PY@tok@nc\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
\expandafter\def\csname PY@tok@nn\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
\expandafter\def\csname PY@tok@ne\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.82,0.25,0.23}{##1}}}
\expandafter\def\csname PY@tok@nv\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
\expandafter\def\csname PY@tok@no\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.53,0.00,0.00}{##1}}}
\expandafter\def\csname PY@tok@nl\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.00}{##1}}}
\expandafter\def\csname PY@tok@ni\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.60,0.60,0.60}{##1}}}
\expandafter\def\csname PY@tok@na\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.49,0.56,0.16}{##1}}}
\expandafter\def\csname PY@tok@nt\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@nd\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.67,0.13,1.00}{##1}}}
\expandafter\def\csname PY@tok@s\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@sd\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@si\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.73,0.40,0.53}{##1}}}
\expandafter\def\csname PY@tok@se\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.73,0.40,0.13}{##1}}}
\expandafter\def\csname PY@tok@sr\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.40,0.53}{##1}}}
\expandafter\def\csname PY@tok@ss\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
\expandafter\def\csname PY@tok@sx\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@m\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@gh\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}}
\expandafter\def\csname PY@tok@gu\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.50,0.00,0.50}{##1}}}
\expandafter\def\csname PY@tok@gd\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.63,0.00,0.00}{##1}}}
\expandafter\def\csname PY@tok@gi\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.63,0.00}{##1}}}
\expandafter\def\csname PY@tok@gr\endcsname{\def\PY@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}}
\expandafter\def\csname PY@tok@ge\endcsname{\let\PY@it=\textit}
\expandafter\def\csname PY@tok@gs\endcsname{\let\PY@bf=\textbf}
\expandafter\def\csname PY@tok@gp\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}}
\expandafter\def\csname PY@tok@go\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}}
\expandafter\def\csname PY@tok@gt\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.27,0.87}{##1}}}
\expandafter\def\csname PY@tok@err\endcsname{\def\PY@bc##1{\setlength{\fboxsep}{0pt}\fcolorbox[rgb]{1.00,0.00,0.00}{1,1,1}{\strut ##1}}}
\expandafter\def\csname PY@tok@kc\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@kd\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@kn\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@kr\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@bp\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@fm\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
\expandafter\def\csname PY@tok@vc\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
\expandafter\def\csname PY@tok@vg\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
\expandafter\def\csname PY@tok@vi\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
\expandafter\def\csname PY@tok@vm\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
\expandafter\def\csname PY@tok@sa\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@sb\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@sc\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@dl\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@s2\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@sh\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@s1\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@mb\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@mf\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@mh\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@mi\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@il\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@mo\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@ch\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
\expandafter\def\csname PY@tok@cm\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
\expandafter\def\csname PY@tok@cpf\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
\expandafter\def\csname PY@tok@c1\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
\expandafter\def\csname PY@tok@cs\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}

\def\PYZbs{\char`\\}
\def\PYZus{\char`\_}
\def\PYZob{\char`\{}
\def\PYZcb{\char`\}}
\def\PYZca{\char`\^}
\def\PYZam{\char`\&}
\def\PYZlt{\char`\<}
\def\PYZgt{\char`\>}
\def\PYZsh{\char`\#}
\def\PYZpc{\char`\%}
\def\PYZdl{\char`\$}
\def\PYZhy{\char`\-}
\def\PYZsq{\char`\'}
\def\PYZdq{\char`\"}
\def\PYZti{\char`\~}
% for compatibility with earlier versions
\def\PYZat{@}
\def\PYZlb{[}
\def\PYZrb{]}
\makeatother


    % For linebreaks inside Verbatim environment from package fancyvrb. 
    \makeatletter
        \newbox\Wrappedcontinuationbox 
        \newbox\Wrappedvisiblespacebox 
        \newcommand*\Wrappedvisiblespace {\textcolor{red}{\textvisiblespace}} 
        \newcommand*\Wrappedcontinuationsymbol {\textcolor{red}{\llap{\tiny$\m@th\hookrightarrow$}}} 
        \newcommand*\Wrappedcontinuationindent {3ex } 
        \newcommand*\Wrappedafterbreak {\kern\Wrappedcontinuationindent\copy\Wrappedcontinuationbox} 
        % Take advantage of the already applied Pygments mark-up to insert 
        % potential linebreaks for TeX processing. 
        %        {, <, #, %, $, ' and ": go to next line. 
        %        _, }, ^, &, >, - and ~: stay at end of broken line. 
        % Use of \textquotesingle for straight quote. 
        \newcommand*\Wrappedbreaksatspecials {% 
            \def\PYGZus{\discretionary{\char`\_}{\Wrappedafterbreak}{\char`\_}}% 
            \def\PYGZob{\discretionary{}{\Wrappedafterbreak\char`\{}{\char`\{}}% 
            \def\PYGZcb{\discretionary{\char`\}}{\Wrappedafterbreak}{\char`\}}}% 
            \def\PYGZca{\discretionary{\char`\^}{\Wrappedafterbreak}{\char`\^}}% 
            \def\PYGZam{\discretionary{\char`\&}{\Wrappedafterbreak}{\char`\&}}% 
            \def\PYGZlt{\discretionary{}{\Wrappedafterbreak\char`\<}{\char`\<}}% 
            \def\PYGZgt{\discretionary{\char`\>}{\Wrappedafterbreak}{\char`\>}}% 
            \def\PYGZsh{\discretionary{}{\Wrappedafterbreak\char`\#}{\char`\#}}% 
            \def\PYGZpc{\discretionary{}{\Wrappedafterbreak\char`\%}{\char`\%}}% 
            \def\PYGZdl{\discretionary{}{\Wrappedafterbreak\char`\$}{\char`\$}}% 
            \def\PYGZhy{\discretionary{\char`\-}{\Wrappedafterbreak}{\char`\-}}% 
            \def\PYGZsq{\discretionary{}{\Wrappedafterbreak\textquotesingle}{\textquotesingle}}% 
            \def\PYGZdq{\discretionary{}{\Wrappedafterbreak\char`\"}{\char`\"}}% 
            \def\PYGZti{\discretionary{\char`\~}{\Wrappedafterbreak}{\char`\~}}% 
        } 
        % Some characters . , ; ? ! / are not pygmentized. 
        % This macro makes them "active" and they will insert potential linebreaks 
        \newcommand*\Wrappedbreaksatpunct {% 
            \lccode`\~`\.\lowercase{\def~}{\discretionary{\hbox{\char`\.}}{\Wrappedafterbreak}{\hbox{\char`\.}}}% 
            \lccode`\~`\,\lowercase{\def~}{\discretionary{\hbox{\char`\,}}{\Wrappedafterbreak}{\hbox{\char`\,}}}% 
            \lccode`\~`\;\lowercase{\def~}{\discretionary{\hbox{\char`\;}}{\Wrappedafterbreak}{\hbox{\char`\;}}}% 
            \lccode`\~`\:\lowercase{\def~}{\discretionary{\hbox{\char`\:}}{\Wrappedafterbreak}{\hbox{\char`\:}}}% 
            \lccode`\~`\?\lowercase{\def~}{\discretionary{\hbox{\char`\?}}{\Wrappedafterbreak}{\hbox{\char`\?}}}% 
            \lccode`\~`\!\lowercase{\def~}{\discretionary{\hbox{\char`\!}}{\Wrappedafterbreak}{\hbox{\char`\!}}}% 
            \lccode`\~`\/\lowercase{\def~}{\discretionary{\hbox{\char`\/}}{\Wrappedafterbreak}{\hbox{\char`\/}}}% 
            \catcode`\.\active
            \catcode`\,\active 
            \catcode`\;\active
            \catcode`\:\active
            \catcode`\?\active
            \catcode`\!\active
            \catcode`\/\active 
            \lccode`\~`\~ 	
        }
    \makeatother

    \let\OriginalVerbatim=\Verbatim
    \makeatletter
    \renewcommand{\Verbatim}[1][1]{%
        %\parskip\z@skip
        \sbox\Wrappedcontinuationbox {\Wrappedcontinuationsymbol}%
        \sbox\Wrappedvisiblespacebox {\FV@SetupFont\Wrappedvisiblespace}%
        \def\FancyVerbFormatLine ##1{\hsize\linewidth
            \vtop{\raggedright\hyphenpenalty\z@\exhyphenpenalty\z@
                \doublehyphendemerits\z@\finalhyphendemerits\z@
                \strut ##1\strut}%
        }%
        % If the linebreak is at a space, the latter will be displayed as visible
        % space at end of first line, and a continuation symbol starts next line.
        % Stretch/shrink are however usually zero for typewriter font.
        \def\FV@Space {%
            \nobreak\hskip\z@ plus\fontdimen3\font minus\fontdimen4\font
            \discretionary{\copy\Wrappedvisiblespacebox}{\Wrappedafterbreak}
            {\kern\fontdimen2\font}%
        }%
        
        % Allow breaks at special characters using \PYG... macros.
        \Wrappedbreaksatspecials
        % Breaks at punctuation characters . , ; ? ! and / need catcode=\active 	
        \OriginalVerbatim[#1,codes*=\Wrappedbreaksatpunct]%
    }
    \makeatother

    % Exact colors from NB
    \definecolor{incolor}{HTML}{303F9F}
    \definecolor{outcolor}{HTML}{D84315}
    \definecolor{cellborder}{HTML}{CFCFCF}
    \definecolor{cellbackground}{HTML}{F7F7F7}
    
    % prompt
    \makeatletter
    \newcommand{\boxspacing}{\kern\kvtcb@left@rule\kern\kvtcb@boxsep}
    \makeatother
    \newcommand{\prompt}[4]{
        \ttfamily\llap{{\color{#2}[#3]:\hspace{3pt}#4}}\vspace{-\baselineskip}
    }
    

    
    % Prevent overflowing lines due to hard-to-break entities
    \sloppy 
    % Setup hyperref package
    \hypersetup{
      breaklinks=true,  % so long urls are correctly broken across lines
      colorlinks=true,
      urlcolor=urlcolor,
      linkcolor=linkcolor,
      citecolor=citecolor,
      }
    % Slightly bigger margins than the latex defaults
    
    \geometry{verbose,tmargin=1in,bmargin=1in,lmargin=1in,rmargin=1in}
    
    

\begin{document}
    
    \maketitle
    
    
\begin{comment}

    
    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{1}{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{o}{\PYZpc{}}\PY{k}{load\PYZus{}ext} ipython\PYZus{}pytest

\PY{c+c1}{\PYZsh{} Run this cell once before trying to run any cell containing a pytest}
\PY{c+c1}{\PYZsh{} Ignore the message that the extension is already loaded if it appears; you do not need}
\PY{c+c1}{\PYZsh{} to reload the extension if it is already loaded.}
\end{Verbatim}
\end{tcolorbox}

    \begin{Verbatim}[commandchars=\\\{\}]

        ---------------------------------------------------------------------------

        ModuleNotFoundError                       Traceback (most recent call last)

        <ipython-input-1-793174c0d870> in <module>
    ----> 1 get\_ipython().run\_line\_magic('load\_ext', 'ipython\_pytest')
          2 
          3 \# Run this cell once before trying to run any cell containing a pytest
          4 \# Ignore the message that the extension is already loaded if it appears; you do not need
          5 \# to reload the extension if it is already loaded.


        \textasciitilde{}/anaconda3/lib/python3.7/site-packages/IPython/core/interactiveshell.py in run\_line\_magic(self, magic\_name, line, \_stack\_depth)
       2315                 kwargs['local\_ns'] = sys.\_getframe(stack\_depth).f\_locals
       2316             with self.builtin\_trap:
    -> 2317                 result = fn(*args, **kwargs)
       2318             return result
       2319 


        </home/robin/anaconda3/lib/python3.7/site-packages/decorator.py:decorator-gen-64> in load\_ext(self, module\_str)


        \textasciitilde{}/anaconda3/lib/python3.7/site-packages/IPython/core/magic.py in <lambda>(f, *a, **k)
        185     \# but it's overkill for just that one bit of state.
        186     def magic\_deco(arg):
    --> 187         call = lambda f, *a, **k: f(*a, **k)
        188 
        189         if callable(arg):


        \textasciitilde{}/anaconda3/lib/python3.7/site-packages/IPython/core/magics/extension.py in load\_ext(self, module\_str)
         31         if not module\_str:
         32             raise UsageError('Missing module name.')
    ---> 33         res = self.shell.extension\_manager.load\_extension(module\_str)
         34 
         35         if res == 'already loaded':


        \textasciitilde{}/anaconda3/lib/python3.7/site-packages/IPython/core/extensions.py in load\_extension(self, module\_str)
         78             if module\_str not in sys.modules:
         79                 with prepended\_to\_syspath(self.ipython\_extension\_dir):
    ---> 80                     mod = import\_module(module\_str)
         81                     if mod.\_\_file\_\_.startswith(self.ipython\_extension\_dir):
         82                         print(("Loading extensions from \{dir\} is deprecated. "


        \textasciitilde{}/anaconda3/lib/python3.7/importlib/\_\_init\_\_.py in import\_module(name, package)
        125                 break
        126             level += 1
    --> 127     return \_bootstrap.\_gcd\_import(name[level:], package, level)
        128 
        129 


        \textasciitilde{}/anaconda3/lib/python3.7/importlib/\_bootstrap.py in \_gcd\_import(name, package, level)


        \textasciitilde{}/anaconda3/lib/python3.7/importlib/\_bootstrap.py in \_find\_and\_load(name, import\_)


        \textasciitilde{}/anaconda3/lib/python3.7/importlib/\_bootstrap.py in \_find\_and\_load\_unlocked(name, import\_)


        ModuleNotFoundError: No module named 'ipython\_pytest'

    \end{Verbatim}
\end{comment}
    
\section{Unit Testing}\label{week-06-functions}

Unit testing is the process of testing units of source code. A unit of
code is the smallest testable part of a piece of software. For our
purposes, the units are Python functions.

The textbook does not discuss this topic in any detail, and for most
students, testing in previous courses amounts to writing a small program
and manually inspecting the output of the program. This notebook
discusses writing tests using the \texttt{pytest} framework. Using a
testing framework has many advantages compared to manual testing:

\begin{itemize}
\tightlist
\item
  a test framework typically produces a summary of the test results
  indicating which tests passed and which tests failed; the programmer
  does not need to manually inspect the output of a program to determine
  the test results
\item
  tools exist that allow tests to be run automatically

  \begin{itemize}
  \tightlist
  \item
    for example, many professional workplaces require their programmers
    to check their code into a centralized
    \href{https://en.wikipedia.org/wiki/Version_control}{version control
    system}; such systems can be configured to automatically run test
    suites whenever code is checked into the system
  \end{itemize}
\item
  test frameworks typically allow the programmer or tester to choose
  which tests should run; there is no easy way to select tests to run
  when manually inspecting the output of a program
\end{itemize}

    \hypertarget{pytest}{%
\subsection{\texorpdfstring{\texttt{pytest}}{pytest}}\label{pytest}}

\href{https://docs.pytest.org/en/stable/}{\texttt{pytest} home page}

The unit test framework that is part of the Python standard is called
\texttt{unittest}. Unfortunately, \texttt{unittest} is not suitable for
the purposes of CISC121 because it requires knowledge of object-oriented
Python.

\texttt{pytest} does not require object-oriented Python and is easily
accessible for CISC121 students. Because it is a third-party framework,
students will need to install it.

\textbf{Installing \texttt{pytest}}

\begin{enumerate}
\def\labelenumi{\arabic{enumi}.}
\tightlist
\item
  In Windows, open a Command Prompt (the \texttt{cmd} program). On Mac,
  open a terminal (the \texttt{Terminal} program).
\item
  In the Command Prompt or terminal type the following command:
\end{enumerate}

\begin{verbatim}
pip3 install -U pytest
\end{verbatim}

\begin{enumerate}
\def\labelenumi{\arabic{enumi}.}
\setcounter{enumi}{2}
\tightlist
\item
  Check that the correct version has been installed correctly by typing
  the following command:
\end{enumerate}

\begin{verbatim}
pytest --version
\end{verbatim}

You should see the output \texttt{pytest\ 6.2.2} (you might see a
version number greater than 6.2.2 depending on when you are reading this
document).

    \hypertarget{unit-testing-basics}{%
\section{Unit testing basics}\label{unit-testing-basics}}

\begin{quote}
Program testing can be a very effective way to show the presence of
bugs, but it is hopelessly inadequate for showing their absence.

Edsger W. Dijkstra
\end{quote}

Programmers try to write correct code, but it is very challenging to
prove that a piece of code is correct (the field of study that tries to
do is called \href{https://en.wikipedia.org/wiki/Formal_methods}{formal
methods}). Instead, most programmers rely on testing to try to find
errors in their code.

When testing a function, we test that the contract of the function is
upheld. In other words, we use test cases where the input argument
values satisfy the preconditions of the function and then test that the
postconditions of the function are satisfied.

Writing a unit test for a Python function is simple in principle:

\begin{enumerate}
\def\labelenumi{\arabic{enumi}.}
\tightlist
\item
  Choose a set of input arguments for the function.
\item
  If the function returns one or more values, determine what the
  expected return values are for the chosen set of input arguments.
\item
  If the function has a side effect, determine what the expected side
  effect is.
\item
  Call the function with the chosen set of input arguments and determine
  if:

  \begin{itemize}
  \tightlist
  \item
    the actual return values are equal to the expected return values
  \item
    the actual side effects are equal to the expected side effects
  \end{itemize}
\end{enumerate}

A set of input arguments, the expected return values, and the expected
side effects make up a \emph{test case}. Testing one function typically
requires using multiple test cases. Determining how many test cases are
needed is beyond the scope of this notebook, but we can explore this
problem somewhat with a few exercises.

    \textbf{Exercise 1} Consider a function having one parameter where the
parameter type is a boolean value. How many possible test cases exist
for the function?

\textbf{Exercise 2} Consider a function having two parameters where both
parameter types are boolean values. How many possible test cases exist
for the function?

\textbf{Exercise 3} Consider a function having three parameters where
all the parameter types are boolean values. How many possible test cases
exist for the function?

\textbf{Exercise 4} Most Python implementations use a 64-bit
representation for float values; this means that there are \(2^{64}\)
distinct float values. Consider a function having two parameters where
both parameter types are float values. How many possible test cases
exist for the function?

    \hypertarget{example-testing-a-function-having-one-return-value}{%
\newpage
\subsection{Example: Testing a function having one return
value}\label{example-testing-a-function-having-one-return-value}}

Consider the \texttt{is\_prime} function from the course textbook
(renamed to use PEP8 function naming convention):

\begin{Shaded}
\begin{Highlighting}[]
\KeywordTok{def}\NormalTok{ is_prime(n):}
    \ControlFlowTok{if}\NormalTok{ n }\OperatorTok{<} \DecValTok{2}\NormalTok{: }
        \ControlFlowTok{return} \VariableTok{False}
\NormalTok{    i }\OperatorTok{=} \DecValTok{2}
    \ControlFlowTok{while}\NormalTok{ i }\OperatorTok{*}\NormalTok{ i }\OperatorTok{<=}\NormalTok{ n:}
        \ControlFlowTok{if}\NormalTok{ n }\OperatorTok{%}\NormalTok{ i }\OperatorTok{==} \DecValTok{0}\NormalTok{: }
            \ControlFlowTok{return} \VariableTok{False}
\NormalTok{        i }\OperatorTok{+=} \DecValTok{1}
    \ControlFlowTok{return} \VariableTok{True}
\end{Highlighting}
\end{Shaded}

To test the function, we first define a test case by choosing an input
argument value and corresponding expected return value. A quick
inspection of the function indicates that any input argument value less
than \(2\) results in \texttt{False} being returned by the method, which
is the correct result. The return value for arguments greater than or
equal \(2\) is less clear. Let's begin with the test case where the
input argument value is \(2\) and the expected return value is
\texttt{True}.

\begin{comment}
\begin{verbatim}
Using pytest in a Jupyter notebook is a bit more complicated because pytest is not part of the standard
Python library. This notebook uses a Jupyter extension named <tt>ipython_pytest</tt> (the source code
which is available <a href="https://github.com/akaihola/ipython_pytest">here</a>). To use the extension,
there is a cell at the top of this notebook contining the line <tt>%load_ext ipython_pytest</tt>
which directs Jupyter to load the extension. Inside a cell where we want to run a pytest test,
we use <tt>%%pytest</tt> which is a Jupyter notebook command defined by the <tt>ipython_pytest</tt>
extension that runs <tt>pytest</tt> using the tests defined in the cell.
\end{verbatim}

\end{comment}
To write a unit test using \texttt{pytest}  we import the \texttt{pytest} module and then define one or
more test functions whose names begins with \texttt{test} or ends with
\texttt{test}. For example, our test case can be implemented as shown
below; 

\begin{comment}

run the two cells below to see the output:

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{ }{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{o}{\PYZpc{}}\PY{k}{load\PYZus{}ext} ipython\PYZus{}pytest

\PY{c+c1}{\PYZsh{} Run this cell once before trying to run any cell containing a pytest}
\PY{c+c1}{\PYZsh{} Ignore the message that the extension is already loaded if it appears; you do not need}
\PY{c+c1}{\PYZsh{} to reload the extension if it is already loaded.}
\end{Verbatim}
\end{tcolorbox}
\end{comment}

\begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
%\prompt{In}{incolor}{ }{\boxspacing}
\begin{comment}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{o}{\PYZpc{}\PYZpc{}}\PY{k}{pytest}

\PYZsh{} Outside of a Jupyter notebook you would import pytest:
\PYZsh{} 
\end{comment}
\begin{verbatim}
	import pytest

	def is_prime(n):
    	if n < 2: 
        	return False
    	i = 2
    	while i * i <= n:
        	if n % i == 0: 
            	return False
        	i += 1
    	return True

	# test function names need to start or end with test

	def test_is_prime_2_true():
    	assert is_prime(2) == True
    	
    	
   # run pytest
   pytest.main(["--capture=sys"])    	
\end{verbatim}
\end{tcolorbox}

    The output should have a line containing \texttt{1\ passed} indicating
that the test case has passed.

The Python \texttt{assert} statement has the form:

\texttt{assert} \emph{expr}

where \emph{expr} is any Python expression whose value can be converted
to \texttt{True} or \texttt{False}. If \emph{expr} evaluates to
\texttt{True} then the \texttt{assert} statement does nothing. If
\emph{expr} evaluates to \texttt{False} then an \texttt{AssertionError}
is raised. In a unit test, \texttt{pytest} handles the
\texttt{AssertionError} and notes that the test has failed.

Let's intentionally introduce an error into \texttt{is\_prime} to see
what a failed test looks like;

\begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
%\prompt{In}{incolor}{ }{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]

import pytest

def is_prime(n):
    # intentional error on next line
    if n <= 2: 
        return False
    i = 2
    while i * i <= n:
        if n % i == 0: 
            return False
        i += 1
    return True


def test_is_prime_2_true():
    n = 2
    assert is_prime(n) == True
    
# run pytest
pytest.main(["--capture=sys"])      
\end{Verbatim}
\end{tcolorbox}

    The \texttt{pytest} output now indicates that the test has failed. In
particular, it shows the input arguments to the function
(\texttt{is\_prime(2)}), the expected return value (\texttt{True}), and
the actual return value (\texttt{False}). For the programmer, knowing
what input values cause a function to fail is valuable information when
debugging the function.

\newpage
    We have one test case where the expected return value is \texttt{True}.
We should also create a test case where the expected return value is
\texttt{False}. The smallest non-prime number is \(4\), so we can add a
second test case where the input argument value is \(4\) and the
expected return value is \texttt{False}

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
%\prompt{In}{incolor}{ }{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
import pytest

def is_prime(n):
    if n \PYZlt{} 2: 
        return False
    i = 2
    while i * i \PYZlt{}= n:
        if n \PYZpc{} i == 0: 
            return False
        i += 1
    return True


def test_is_prime_2_true():
    n = 2
    assert is_prime(n) == True
    
def test_is_prime_4_false():
    n = 4
    assert is_prime(n) == False
    
# run pytest
pytest.main(["--capture=sys"])      
\end{Verbatim}
\end{tcolorbox}
\newpage
    At this point the reader should realize that tests for the
\texttt{is\_prime} function fall into one of two categories: Those where
the expected return value is \texttt{False} and those where the expected
return value is \texttt{True}. Instead of testing a single value in each
test function, we can test multiple different input arguments using a
single function:

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
%\prompt{In}{incolor}{ }{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
import pytest

def is_prime(n):
    if n \PYZlt{} 2: 
        return False
    i = 2
    while i * i \PYZlt{}= n:
        if n \PYZpc{} i == 0: 
            return False
        i += 1
    return True


def test_is_prime_true():
    N = [2, 3, 5, 7, 11, 13, 17]
    for n in N:
        assert is_prime(n) == True
    
def test_is_prime_false():
    N = [4, 6, 8, 9, 10, 12, 14]
    for n in N:
        assert is_prime(n) == False
        
# run pytest
pytest.main(["--capture=sys"])  
        
\end{Verbatim}
\end{tcolorbox}

    The disadvantage with this approach is that a test written this way will
stop on the first test case that fails; the remaining test cases will
not be run. A better way to write such tests is to use a
\href{https://docs.pytest.org/en/stable/parametrize.html}{\emph{parameterized
test}} but this is beyond the scope of CISC121.

    With a bit of reflection, it should be clear to the reader why unit
testing cannot prove that the \texttt{is\_prime} function is correct:
There are an infinite number of possible input arguments to test! Even
worse, for very large input values, we have no good way to determine
what the expected return value should be.
\newpage
    \textbf{Exercise 5} Write a small number of tests for the 
function in the following box. The function is supposed to compute the
length of the hypotenuse of a right triangle with sides of lengths
\texttt{a} and \texttt{b}.

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
%\prompt{In}{incolor}{ }{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
import pytest
import math

def hypot(a, b):
    return math.sqrt(a * a + b * b)

# write your tests here

# run pytest
pytest.main(["--capture=sys"])      
\end{Verbatim}
\end{tcolorbox}
\newpage
    \hypertarget{example-testing-a-function-that-has-a-side-effect}{%
\subsection{Example: Testing a function that has a side
effect}\label{example-testing-a-function-that-has-a-side-effect}}

A function has a side effect if it has some observable effect besides
returning a value. Printing a value is an example of a side effect.
Changing the state of a mutable input argument (such as a list) is another
example of a side effect.

Consider the function \texttt{exchange} that swaps two elements
of a list:

\begin{Shaded}
\begin{Highlighting}[]
\KeywordTok{def}\NormalTok{ exchange(a, i, j):}
    \CommentTok{"""}
\CommentTok{    Swaps two elements of a list.}
\CommentTok{    }
\CommentTok{    Swaps the elements a[i] and a[j] of the list a.}
\CommentTok{    }
\CommentTok{    Parameters}
\CommentTok{    ----------}
\CommentTok{    a : list}
\CommentTok{        A list}
\CommentTok{    i : int}
\CommentTok{        Index of an element to swap}
\CommentTok{    j : int}
\CommentTok{        Index of a second element to swap}
\CommentTok{        }
\CommentTok{    Raises}
\CommentTok{    ------}
\CommentTok{    IndexError}
\CommentTok{        If `i` or `j` is out of range.}
\CommentTok{    """}
    
\NormalTok{    temp }\OperatorTok{=}\NormalTok{ a[i]}
\NormalTok{    a[i] }\OperatorTok{=}\NormalTok{ a[j]}
\NormalTok{    a[j] }\OperatorTok{=}\NormalTok{ temp}
\end{Highlighting}
\end{Shaded}

After calling \texttt{exchange} every element of \texttt{a} should be
unchanged except for the elements at indexes \texttt{i} and \texttt{j}
which should be swapped.

(It may seem strange to call the exchange of the two elements a \textbf{side effect} when that is the entire purpose of the function!  However, this is the terminology we use.)

Testing a function with side effects is similar to testing a function
with a return value. One difference is that we probably have to call the
function that is being tested before the \texttt{assert} statement to
cause the side effect to occur.
\newpage
Let's write a test for \texttt{exchange} where we swap the elements of a
list of length 2:

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
%\prompt{In}{incolor}{ }{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
import pytest

def exchange(a, i, j):
    temp = a[i]
    a[i] = a[j]
    a[j] = temp
    
def test_exchange_len2():
    \PYZsq{}\PYZsq{}\PYZsq{}
    Test for list of length 2.
    \PYZsq{}\PYZsq{}\PYZsq{}
    
    \PYZsh{} input arguments
    a = [\PYZsq{}x\PYZsq{}, \PYZsq{}y\PYZsq{}]
    i = 0
    j = 1
    
    \PYZsh{} expected list
    exp = [\PYZsq{}y\PYZsq{}, \PYZsq{}x\PYZsq{}]
    
    \PYZsh{} call the method to cause the side effect
    exchange(a, i, j)
    
    assert a == exp
\end{Verbatim}
\end{tcolorbox}

    For CISC121, the above test is a good attempt at writing a unit test for
the \texttt{exchange} function. It sets up the input arguments and the
expected side effect correctly, calls the \texttt{exchange} function
using the test case arguments, and then tests if the modified list
\texttt{a} is equal to the expected list \texttt{exp}.
\newpage
A second test case that would be useful to include is a case where the
indexes \texttt{i} and \texttt{j} are equal (corresponding to the case
where no exchange actually occurs); given the existing test, it is easy
to write such a test case:

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
%\prompt{In}{incolor}{ }{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
import pytest

def exchange(a, i, j):
    temp = a[i]
    a[i] = a[j]
    a[j] = temp
    
def test_exchange_len2():
    \PYZsq{}\PYZsq{}\PYZsq{}
    Test for list of length 2.
    \PYZsq{}\PYZsq{}\PYZsq{}
    
    \PYZsh{} input arguments
    a = [\PYZsq{}x\PYZsq{}, \PYZsq{}y\PYZsq{}]
    i = 0
    j = 1
    
    \PYZsh{} expected list
    exp = [\PYZsq{}y\PYZsq{}, \PYZsq{}x\PYZsq{}]
    
    \PYZsh{} call the method to cause the side effect
    exchange(a, i, j)
    
    assert a == exp
    
def test_exchange_len2_same_indexes():
    \PYZsq{}\PYZsq{}\PYZsq{}
    Test for list of length 2 with same indexes.
    \PYZsq{}\PYZsq{}\PYZsq{}
    
    \PYZsh{} input arguments
    a = [\PYZsq{}x\PYZsq{}, \PYZsq{}y\PYZsq{}]
    i = 1
    j = 1
    
    \PYZsh{} expected list
    exp = [\PYZsq{}x\PYZsq{}, \PYZsq{}y\PYZsq{}]
    
    \PYZsh{} call the method to cause the side effect
    exchange(a, i, j)
    
    assert a == exp
    
# run pytest
pytest.main(["--capture=sys"])      
\end{Verbatim}
\end{tcolorbox}

    The above tests are useful, but they are technically asserting the wrong
condition. See the sections near the end of this note starting with
the box titled \textbf{Extra material: How the exchange tests could be
better} for details.

    \textbf{Exercise 6} Write a small number of tests for the function
\texttt{min\_to\_front} in the following box. The purpose of the function is
that it moves the smallest element of the list to the front of the list
and puts the element that was at the front of the list somewhere else in
the list.

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{ }{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]

def min_to_front(a):
    if len(a) == 0:
        raise ValueError(\PYZsq{}min_to_front(): no minimum element in an empty list\PYZsq{})
    
    if len(a) == 1:
        \PYZsh{} list of length 1 already has its minimum element at the front of the list
        return
    
    min_elem = a[0]
    min_index = 0
    for i in range(1, len(a)):
        ai = a[i]
        if ai \PYZlt{} min_elem:
            min_elem = ai
            min_index = i
    front = a[0]
    a.pop(min_index)
    a[0] = min_elem
    a.append(front)
    
\end{Verbatim}
\end{tcolorbox}

\newpage
    \hypertarget{example-testing-a-slightly-more-complicated-function}{%
\subsection{Example: Testing a slightly more complicated
function}\label{example-testing-a-slightly-more-complicated-function}}

The above examples are useful for introducing the concept of unit
testing using \texttt{pyttest} but the tested functions are already
correctly implemented. Consider the following function that is supposed
to return the second largest element in a list having at least 2
elements:

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
%\prompt{In}{incolor}{ }{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{k}{def} \PY{n+nf}{second_largest}\PY{p}{(}\PY{n}{a}\PY{p}{)}\PY{p}{:}
    \PY{l+s+sd}{\PYZsq{}\PYZsq{}\PYZsq{}}
\PY{l+s+sd}{    Return the second largest element in a list.}
\PY{l+s+sd}{    }
\PY{l+s+sd}{    The list `a` is assumed to have at least two elements that can be compared}
\PY{l+s+sd}{    using the \PYZgt{}= operator.}
\PY{l+s+sd}{    \PYZsq{}\PYZsq{}\PYZsq{}}
    
    \PY{c+c1}{\PYZsh{} look at the first two elements}
    \PY{n}{largest} \PY{o}{=} \PY{n+nb}{max}\PY{p}{(}\PY{n}{a}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{]}\PY{p}{,} \PY{n}{a}\PY{p}{[}\PY{l+m+mi}{1}\PY{p}{]}\PY{p}{)}
    \PY{n}{second} \PY{o}{=} \PY{n+nb}{min}\PY{p}{(}\PY{n}{a}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{]}\PY{p}{,} \PY{n}{a}\PY{p}{[}\PY{l+m+mi}{1}\PY{p}{]}\PY{p}{)}
    
    \PY{c+c1}{\PYZsh{} look at the remaining elements}
    \PY{k}{for} \PY{n}{i} \PY{o+ow}{in} \PY{n+nb}{range}\PY{p}{(}\PY{l+m+mi}{2}\PY{p}{,} \PY{n+nb}{len}\PY{p}{(}\PY{n}{a}\PY{p}{)}\PY{p}{)}\PY{p}{:}
        \PY{n}{elem} \PY{o}{=} \PY{n}{a}\PY{p}{[}\PY{n}{i}\PY{p}{]}
        \PY{k}{if} \PY{n}{elem} \PY{o}{\PYZgt{}}\PY{o}{=} \PY{n}{largest}\PY{p}{:}
            \PY{n}{second} \PY{o}{=} \PY{n}{largest}
            \PY{n}{largest} \PY{o}{=} \PY{n}{elem}
    \PY{k}{return} \PY{n}{second}
\end{Verbatim}
\end{tcolorbox}

    Following the previous examples, we can easily write a unit test by
creating a list with two or more elements and setting the expected
return value to be equal to the second largest element of the input
list. The following box shows three different tests:
\newpage
    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
%\prompt{In}{incolor}{ }{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
import pytest

def second_largest(a):
    \PYZsq{}\PYZsq{}\PYZsq{}
    Return the second largest element in a list.
    
    The list `a` is assumed to have at least two elements that can be compared
    using the \PYZgt{}= operator.
    \PYZsq{}\PYZsq{}\PYZsq{}
    
    \PYZsh{} look at the first two elements
    largest = max(a[0], a[1])
    second = min(a[0], a[1])
    
    \PYZsh{} look at the remaining elements
    for i in range(2, len(a)):
        elem = a[i]
        if elem \PYZgt{}= largest:
            second = largest
            largest = elem
    return second


def test_list_len2_1():
    a = [1, 2]
    exp = 1
    assert second_largest(a) == exp
    
def test_list_len2_2():
    a = [2, 1]
    exp = 1
    assert second_largest(a) == exp

def test_list_len5():
    a = [1, 8, 10, 5, 12]
    exp = 10
    assert second_largest(a) == exp
    
# run pytest
pytest.main(["--capture=sys"])      
\end{Verbatim}
\end{tcolorbox}

    The function passes all three test cases but there is an error in the
function.

\textbf{Exercise 7} Can you find the error in the function
\texttt{second\_largest}?  (Don't go to the next page until you have tried this exercise.)

\newpage
The error in the function \texttt{second\_largest} is that it assigns a
value to \texttt{second} only when a new largest value is found in the
list; this means that the function will fail to find the correct second
largest value if it comes after the largest value in the list.

Note that the second test case uses a list where the second largest
element comes after the largest element, but the function is written in
such a way that it works correctly for lists of length 2.

Adding a fourth test case will reveal the error:

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
%\prompt{In}{incolor}{ }{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
import pytest

def second_largest(a):
    \PYZsq{}\PYZsq{}\PYZsq{}
    Return the second largest element in a list.
    
    The list `a` is assumed to have at least two elements that can be compared
    using the \PYZgt{}= operator.
    \PYZsq{}\PYZsq{}\PYZsq{}
    
    \PYZsh{} look at the first two elements
    largest = max(a[0], a[1])
    second = min(a[0], a[1])
    
    \PYZsh{} look at the remaining elements
    for i in range(2, len(a)):
        elem = a[i]
        if elem \PYZgt{}= largest:
            second = largest
            largest = elem
    return second


def test_list_len2_1():
    a = [1, 2]
    exp = 1
    assert second_largest(a) == exp
    
def test_list_len2_2():
    a = [2, 1]
    exp = 1
    assert second_largest(a) == exp

def test_list_len5_1():
    a = [1, 8, 10, 5, 12]
    exp = 10
    assert second_largest(a) == exp
    
def test_list_len5_2():
    a = [1, 8, 10, 5, 9]
    exp = 9
    assert second_largest(a) == exp
    
# run pytest
pytest.main(["--capture=sys"])      
\end{Verbatim}
\end{tcolorbox}

    This example again illustrates why it is impossible to use testing to
prove that a method is correct: There are an infinite number of input
lists and we cannot possibly test them all. If we fail to use a test
case that reveals an error then we may erroneously conclude that the
function is correct.

    \hypertarget{extra-material-how-the-exchange-tests-could-be-better}{%
\subsection{\texorpdfstring{Extra material: How the \texttt{exchange}
tests could be
better}{Extra material: How the exchange tests could be better}}\label{extra-material-how-the-exchange-tests-could-be-better}}

The \texttt{exchange} test shown earlier in this notebook does not
actually correctly test the behavior of \texttt{exchange}.
\texttt{exchange} is supposed to swap two elements of a list; in other
words, after \texttt{exchange(a,\ i,\ j)} finishes running:

\begin{itemize}
\tightlist
\item
  the element at \texttt{a{[}i{]}} should refer to the same object that
  \texttt{a{[}j{]}} referred to immediately before \texttt{exchange} was
  called
\item
  the element at \texttt{a{[}j{]}} should refer to the same object that
  \texttt{a{[}i{]}} referred to immediately before \texttt{exchange} was
  called
\item
  every element in \texttt{a} not at index \texttt{i} or \texttt{j}
  should refer to the same object that it referred to immediately before
  \texttt{exchange} was called
\end{itemize}

The test written for \texttt{exchange} uses \texttt{==} to test if the
list \texttt{a} is equal to a list where the elements have been
correctly swapped. Unfortunately, \texttt{==} tests if two objects are
equal. For a list, \texttt{==} tests if all of the corresponding
elements of two lists are equal. Here is an example of two lists that
are equal, but do not contain references to the same objects:

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{ }{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
\PY{n}{a} \PY{o}{=} \PY{p}{[}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{hello world}\PY{l+s+s1}{\PYZsq{}}\PY{p}{]}
\PY{n}{b} \PY{o}{=} \PY{p}{[}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{hello world}\PY{l+s+s1}{\PYZsq{}}\PY{p}{]}
\PY{n+nb}{print}\PY{p}{(}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{equal lists?:}\PY{l+s+s1}{\PYZsq{}}\PY{p}{,} \PY{n}{a} \PY{o}{==} \PY{n}{b}\PY{p}{)}
\PY{n+nb}{print}\PY{p}{(}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{same elements?:}\PY{l+s+s1}{\PYZsq{}}\PY{p}{,} \PY{n}{a}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{]} \PY{o+ow}{is} \PY{n}{b}\PY{p}{[}\PY{l+m+mi}{0}\PY{p}{]}\PY{p}{)}
\end{Verbatim}
\end{tcolorbox}
\newpage
    To test if two references refer to the same object we can use the Python
operator \texttt{is}. Re-writing the previous version of the test leads
to the following:

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
%\prompt{In}{incolor}{ }{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
import pytest

def exchange(a, i, j):
    temp = a[i]
    a[i] = a[j]
    a[j] = temp
    
def test_exchange_len2():
    \PYZsh{} input arguments
    a = [\PYZsq{}x\PYZsq{}, \PYZsq{}y\PYZsq{}]
    i = 0
    j = 1
    
    \PYZsh{} copy of a
    copy = a[:]
    
    \PYZsh{} call the method to cause the side effect
    exchange(a, i, j)
    
    assert a[i] is copy[j]
    assert a[j] is copy[i]
    
# run pytest
pytest.main(["--capture=sys"])      
\end{Verbatim}
\end{tcolorbox}

    In the above test, the list \texttt{copy} is a copy of the list
\texttt{a} before the swap occurs: \texttt{copy{[}0{]}} and
\texttt{a{[}0{]}} are references to the same object, and
\texttt{copy{[}1{]}} and \texttt{a{[}1{]}} are references to the same
object. Calling \texttt{exchange} modifies the list \texttt{a} but does
not modify the list \texttt{copy}. After calling \texttt{exchange},
\texttt{a{[}i{]}} and \texttt{copy{[}j{]}} should refer to the same
object, and \texttt{a{[}j{]}} and \texttt{copy{[}i{]}} should refer to
the same object. Notice the use of \texttt{is} in the test to test that
the references refer to the same object instead of using \texttt{==} to
test if the objects are equal.
\newpage
Now let's write a test using a slightly longer list:

    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
%\prompt{In}{incolor}{ }{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
import pytest

def exchange(a, i, j):
    temp = a[i]
    a[i] = a[j]
    a[j] = temp
    
    
def test_exchange_len2():
    \PYZsh{} input arguments
    a = [\PYZsq{}x\PYZsq{}, \PYZsq{}y\PYZsq{}]
    i = 0
    j = 1
    
    \PYZsh{} copy of a
    copy = a[:]
    
    \PYZsh{} call the method to cause the side effect
    exchange(a, i, j)
    
    assert a[i] is copy[j]
    assert a[j] is copy[i]
    
    
def test_exchange_len3():
    \PYZsh{} input arguments
    a = [\PYZsq{}x\PYZsq{}, \PYZsq{}y\PYZsq{}, \PYZsq{}z\PYZsq{}]
    i = 1
    j = 2
    
    \PYZsh{} copy of a
    copy = a[:]
    
    \PYZsh{} call the method to cause the side effect
    exchange(a, i, j)
    
    for k in range(0, len(a)):
        if k == i:
            assert a[k] is copy[j]
        elif k == j:
            assert a[k] is copy[i]
        else:
            assert a[k] is copy[k]
    
# run pytest
pytest.main(["--capture=sys"])      
\end{Verbatim}
\end{tcolorbox}

    For lists longer than length 2 we should test that the elements whose
indexes are not equal to \texttt{i} or \texttt{j} are unchanged by the
\texttt{exchange} function, so there is now a third \texttt{assert}
statement.

The observant reader will recognize that both of the tests above differ
only in the input arguments that are used. We should move the common
code into a separate function like this (see next page):
\newpage
    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
%\prompt{In}{incolor}{ }{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]
import pytest

def exchange(a, i, j):
    temp = a[i]
    a[i] = a[j]
    a[j] = temp


def exchange_test_impl(a, i, j):
    \PYZsh{} copy of a
    copy = a[:]
    
    \PYZsh{} call the method to cause the side effect
    exchange(a, i, j)
    
    for k in range(0, len(a)):
        if k == i:
            assert a[k] is copy[j]
        elif k == j:
            assert a[k] is copy[i]
        else:
            assert a[k] is copy[k]
    
def test_exchange_len2():
    \PYZsh{} input arguments
    a = [\PYZsq{}x\PYZsq{}, \PYZsq{}y\PYZsq{}]
    i = 0
    j = 1
    \PYZsh{} call the test implementation
    exchange_test_impl(a, i, j)
    
    
def test_exchange_len3():
    \PYZsh{} input arguments
    a = [\PYZsq{}x\PYZsq{}, \PYZsq{}y\PYZsq{}, \PYZsq{}z\PYZsq{}]
    i = 1
    j = 2
    \PYZsh{} call the test implementation
    exchange_test_impl(a, i, j)

# run pytest
pytest.main(["--capture=sys"])      
\end{Verbatim}
\end{tcolorbox}

    The function \texttt{exchange\_test\_impl} is the function that actually
implements the testing logic (the \texttt{\_impl} is an abbreviation of
\emph{implementation}). We have to be careful when naming this function
not to start or end the name with \texttt{test} otherwise
\texttt{pytest} will think that it is a separate test function.
\begin{comment}
    \begin{tcolorbox}[breakable, size=fbox, boxrule=1pt, pad at break*=1mm,colback=cellbackground, colframe=cellborder]
\prompt{In}{incolor}{ }{\boxspacing}
\begin{Verbatim}[commandchars=\\\{\}]

\end{Verbatim}
\end{tcolorbox}
\end{comment}

    % Add a bibliography block to the postdoc
    
    
    
\end{document}
