Skip to content
Snippets Groups Projects
Commit 6718cd68 authored by W. Spencer Smith's avatar W. Spencer Smith
Browse files

Removal of redundant T05 slides

parent ca5665c2
No related branches found
No related tags found
No related merge requests found
File deleted
% Define Document Class
% Class Options Include:
% notes, notesonly, handout, trans,
% hidesubsections, shadesubsections,
% inrow, blue, red, grey, brown
%--------------------------------------------------------------------------
\documentclass[xcolor=dvipsnames, shownotes, colorlinks]{beamer}
%--------------------------------------------------------------------------
% -------------------------------------------------------------------------
% Define Package Theme
%--------------------------------------------------------------------------
\usepackage{color}
\usepackage[T1]{fontenc}
%% \usepackage{fix-cm}
\usepackage{hyperref}
\hypersetup{
urlcolor=cyan,
linkcolor=white
}
\usepackage{subfigure}
\usepackage{graphicx}
\graphicspath{ {/} }
\usepackage{enumerate}
\usetheme{Antibes}
\setbeamertemplate{sidebar}[right]
\setbeamertemplate{caption}[numbered]
\usepackage{listings} % Code formatting
\usepackage{lstautogobble}
\usepackage{dirtytalk}
\lstset{
language=[LaTeX]TeX,
basicstyle=\ttfamily\scriptsize,
tabsize=2,
breaklines=true,
prebreak=\raisebox{0ex}[0ex][0ex]{\ensuremath{\hookleftarrow}},
frame=single,
showstringspaces=true,
showspaces=false,
keywordstyle=\color{blue},
stringstyle=\color{magenta},
commentstyle=\color{ForestGreen},
morekeywords={maketitle, tableofcontents, subsection, subsubsection, includegraphics, toprule, midrule, bottomrule},
autogobble=true
}
%------------------------------------------------------------------------------
% Commands
%------------------------------------------------------------------------------
\newcommand*\oldmacro{}%
\let\oldmacro\insertshorttitle%
\renewcommand*\insertshorttitle{%
\oldmacro\hfill%
\insertframenumber\,/\,\inserttotalframenumber}
% Figure Source
\usepackage[absolute,overlay]{textpos}
\setbeamercolor{framesource}{fg=gray}
\setbeamerfont{framesource}{size=\tiny}
\newcommand{\source}[1]{\begin{textblock*}{\paperwidth}(-5pt,\textheight)
\begin{beamercolorbox}[ht=0.5cm,right]{framesource}
\usebeamerfont{framesource}\usebeamercolor[fg]{framesource} Source: {#1}
\end{beamercolorbox}
\end{textblock*}}
%--------------------------------------------------------------------------
% Presentation Title Slide
%--------------------------------------------------------------------------
\title{Unit Testing - pytest}
\subtitle{CS 2ME3/SE 2AA4}
\author{Zichen Jiang\\
Owen Huyn}
\institute{Department of Computing and Software\\
McMaster University\\ }
\date{\today}
%--------------------------------------------------------------------------
% Document
% To add notes to the slides use: \note{}
% Add \section{} or \subsection{} for use in table of contents
%--------------------------------------------------------------------------
\begin{document}
% Create Title Slide
\begin{frame}
\maketitle
\end{frame}
\section[Outline]{}
% Create Table of Contents Slide - Outline
\begin{frame}
\frametitle{Outline}
{\hypersetup{linkcolor=black}
\tableofcontents
}
\end{frame}
% -----------------------------------------------------
\section{Introduction}
% -----------------------------------------------------
\begin{frame}[fragile]
\frametitle{What is Unit Testing}
\begin{itemize}
\item{Unit testing verifies that individual units of code (usually functions) work as intended}
\item{Designed to be \textbf{simple}, easy to write and run}
\item{You can test both from a blackbox perspective and a whitebox perspective}
\end{itemize}
\end{frame}
\begin{frame}[fragile]
\frametitle{Who writes unit tests}
\begin{itemize}
\item{Developers should test their own code!}
\item{The person who wrote the code usually has the best understanding of what their code does}
\end{itemize}
\end{frame}
\begin{frame}[fragile]
\frametitle{Why Unit Test?}
\begin{itemize}
\item{You can catch bugs much earlier}
\item{Provides documentation on a specific function}
\item{Helps developer improve the implementation/design of a function}
\item{Every good developer should be a good tester too!\\
No one likes to work with someone who doesn't verify/test if their code works.}
\end{itemize}
\end{frame}
% -----------------------------------------------------
\section{pytest}
% -----------------------------------------------------
\begin{frame}[fragile]
\frametitle{What is pytest}
\begin{itemize}
\item{pytest is a framework that makes it easy to write small tests}
\item{Similar to JUnit (Java), CppUnit (C++)}
\item{Knowledge is transferable to another xUnit framework regardless of language}
\end{itemize}
\end{frame}
\begin{frame}[fragile]
\frametitle{Getting Started}
\begin{itemize}
\item{Installing pytest is very simple, simply run the following command in your command line}
\item{\texttt{pip install -U pytest }}
\item{For more information, visit \href{https://docs.pytest.org/en/latest/getting-started.html} {pytest Installation and Getting Started}}
\end{itemize}
\end{frame}
% -----------------------------------------------------
\section{Demo}
% -----------------------------------------------------
\begin{frame}[fragile]
\frametitle{Demo}
\begin{itemize}
\item{Let's get started, I encourage everyone to pull out their laptops and follow along.}
\item{We will test A1 from last year, which was introduced in the past tutorials}
\item{Don't be afraid to ask any questions!}
\end{itemize}
\end{frame}
\begin{frame}[fragile]
\frametitle{Create our first unit test file}
\begin{itemize}
\item{To start, create a new Python file called test\_circles.py in the same directory of our file that we want to test}
\item{You can do this from the command line or any text editor of your choice. Don't be afraid to ask any questions!}
\end{itemize}
\end{frame}
\begin{frame}[fragile]
\frametitle{Create our first test template}
\begin{itemize}
\item{To start with our unit test, follow this template:}
\end{itemize}
\begin{lstlisting}[language=Python]
import pytest
class TestCircles:
\end{lstlisting}
\begin{enumerate}
\item{Import the pytest library}
\item{Write a unit testing class starting with the word \texttt{Test}}
\end{enumerate}
\end{frame}
\begin{frame}[fragile]
\frametitle{What is Assert?}
\begin{itemize}
\item{ Wikipedia: \say{... an assertion is a statement that a predicate (Boolean-valued function, i.e. a true-false expression) is expected to always be true at that point in the code. If an assertion evaluates to false at run time, an assertion failure results, which typically causes the program to crash, or to throw an assertion exception.}}
\item{Basically, if whatever follows assert is true, it will continue. Otherwise the test will fail and stop running.}
\end{itemize}
\end{frame}
\begin{frame}[fragile]
\frametitle{Example of Assert?}
\begin{itemize}
\item{To assert something to be true, you can write}
\begin{lstlisting}[language=Python]
assert <true statement>
\end{lstlisting}
\item{To assert something to be false, you can write}
\begin{lstlisting}[language=Python]
assert not <false statement>
\end{lstlisting}
\end{itemize}
\end{frame}
\begin{frame}[fragile]
\frametitle{Writing our first test}
\begin{lstlisting}[language=Python]
import pytest
from CircleADT import *
class TestCircles:
def test_xcoord_are_equal(self):
circle = CircleT(1,2,3)
assert circle.xcoord() == 1
def test_xcoord_are_not_equal(self):
circle = CircleT(1,2,3)
assert not (circle.xcoord() == 2)
# or `assert circle.xcoord() != 2'
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]
\frametitle{Running our first test}
\begin{itemize}
\item{Run this command in your command prompt inside the folder of your test file: \texttt{pytest test\_circles.py}}
\item{To run all tests within the directory, just run \texttt{pytest}. It will search for all files starting with "test\_" and run all methods starting with "test\_"}
\begin{figure}[b]
{\includegraphics[width=10cm]{test-result}}
\end{figure}
\end{itemize}
\end{frame}
\begin{frame}[fragile]
\frametitle{What if a test failed?}
\begin{itemize}
\item{Say we have the following code:}
\end{itemize}
\begin{lstlisting}[language=Python]
import pytest
from CircleADT import *
class TestCircles:
def test_xcoord_are_equal(self):
circle = CircleT(1,2,3)
assert circle.xcoord() == 1
def test_xcoord_are_not_equal(self):
circle = CircleT(1,2,3)
assert circle.xcoord() != 1
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]
\frametitle{What if a test failed?}
\begin{figure}[b]
{\includegraphics[width=10cm]{test-result-fail}}
\end{figure}
\end{frame}
\begin{frame}[fragile]
\frametitle{Floating Point assertions}
\begin{itemize}
\item{\texttt{approx(expected, rel=None, abs=None, nan\_ok=False)}}
\begin{itemize}
\item{\texttt{rel}: relative tolerance}
\item{\texttt{abs}: absolute tolerance}
\item{\texttt{nan\_ok}: facilitates comparing arrays that use NaN to mean "no data"}
\end{itemize}
\item{By default, \texttt{approx} considers numbers within a relative tolerance of 1e-6 and absolute tolerance of 1e-12 of its expected value to be equal. }
\end{itemize}
\begin{lstlisting}[language=Python, escapechar=!]
>>> 1.0001 == approx(1)
False
>>> 1.0001 == approx(1, rel=1e-3)
True
>>> 1.0001 == approx(1, abs=1e-3)
True
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]
\frametitle{Redundant code in tests}
\begin{lstlisting}[language=Python, escapechar=!]
import pytest
from CircleADT import *
class TestCircles:
def test_xcoord_are_equal(self):
!\colorbox{yellow}{circle = CircleT(1,2,3)}!
assert circle.xcoord() == 1
def test_xcoord_are_not_equal(self):
!\colorbox{yellow}{circle = CircleT(1,2,3)}!
assert not circle.xcoord() == 1
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]
\frametitle{Cleaned up code}
\begin{lstlisting}[language=Python, escapechar=!]
import pytest
from CircleADT import *
class TestCircles:
def setup_method(self, method):
self.circle = CircleT(1,2,3)
def teardown_method(self, method):
self.circle = None
def test_xcoord_are_equal(self):
assert self.circle.xcoord() == 1
def test_xcoord_are_not_equal(self):
assert not self.circle.xcoord() == 2
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]
\frametitle{Setup and Teardown}
\begin{itemize}
\item{\texttt{setup\_class(cls)}}
\begin{itemize}
\item{setup any state specific to the execution of the given class}
\end{itemize}
\item{\texttt{teardown\_class(cls)}}
\begin{itemize}
\item{teardown any state that was previously setup with a call to \texttt{setup\_class}.}
\end{itemize}
\item{\texttt{setup\_method(self, method)}}
\begin{itemize}
\item{setup any state tied to the execution of the given method in a class. \texttt{setup\_method} is invoked for every test method of a class.}
\end{itemize}
\item{\texttt{teardown\_method(self, method)}}
\begin{itemize}
\item{teardown any state that was previously setup with a \texttt{setup\_method} call.}
\end{itemize}
\end{itemize}
\end{frame}
\begin{frame}[fragile]
\frametitle{Asserting about exceptions}
\begin{itemize}
\item{It is very important in unit testing to check for edge cases and behaviour in the case of unexpected input.}
\item{If a function raises an exception in some cases, you should include those cases in your unit testing as well.}
\item{You can do so by using a context manager called pytest.raises.}
\end{itemize}
\begin{lstlisting}[language=Python, escapechar=!]
import pytest
def test_zero_division():
with pytest.raises(ZeroDivisionError):
1 / 0
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]
\frametitle{Asserting about exceptions}
\begin{itemize}
\item{If an exception is not raised in a pytest.raises block, the test will fail.}
\end{itemize}
\begin{lstlisting}[language=Python, escapechar=!]
import pytest
def test_zero_division():
with pytest.raises(ZeroDivisionError):
2 / 1
\end{lstlisting}
\begin{itemize}
\item{If you run this test, it will give the result:}
\end{itemize}
\begin{figure}[b]
{\includegraphics[width=8cm]{exception-not-raised}}
\end{figure}
\end{frame}
% -----------------------------------------------------
\section{Code Coverage}
% -----------------------------------------------------
\begin{frame}[fragile]
\frametitle{How much should I test?}
\begin{itemize}
\item {Test all requirements in each function}
\item{Cover edge cases that may cause unintended consequences}
\item{Have an acceptable amount of
\href{https://en.wikipedia.org/wiki/Code_coverage}{code coverage}}
\item{Code coverage will be covered in more detail in future lectures}
\end{itemize}
\end{frame}
\begin{frame}[fragile]
\frametitle{Code Coverage}
\begin{itemize}
\item{Function coverage: has each function (or subroutine) in the program been called?}
\item{Statement coverage: has each statement in the program been executed?}
\end{itemize}
\end{frame}
\begin{frame}[fragile]
\frametitle{Code Coverage}
\begin{itemize}
\item{Branch coverage: has each branch of each control structure (such as in if and case statements) been executed?}
\begin{itemize}
\item{For example, given an if statement, have both the true and false branches been executed?}
\item{Another way of saying this is, has every edge in the program been executed?}
\end{itemize}
\item{Condition coverage (or predicate coverage): has each Boolean sub-expression evaluated both to true and false?}
\end{itemize}
\end{frame}
\begin{frame}[fragile]
\frametitle{Pytest plugin for measuring coverage}
\begin{itemize}
\item{\url{https://pypi.python.org/pypi/pytest-cov}}
\item{Install with pip: \texttt{pip install pytest-cov}}
\end{itemize}
\end{frame}
\begin{frame}[fragile]
\frametitle{Running the coverage plugin}
\begin{itemize}
\item{In the source code directory, run \texttt{pytest -{}-cov}}
\item{
\begin{figure}[b]
{\includegraphics[width=8cm]{test-coverage}}
\end{figure}
}
\item{We can see that \texttt{CircleADT.py} has onlyl 51\% coverage. This is because only the methods \texttt{xcoord} and \texttt{ycoord} were tested}
\end{itemize}
\end{frame}
\begin{frame}[fragile]
\frametitle{Exercise}
\begin{itemize}
\item{The rest of the methods are left for you as practices}
\item{You can Refer to testStatistics.py for a more complete breakdown on how to test complicated functions}
\end{itemize}
\end{frame}
\begin{frame}[fragile]
\frametitle{References}
\begin{itemize}
\item{\url{https://docs.pytest.org/en/latest/xunit_setup.html}}
\item{\url{https://en.wikipedia.org/wiki/Code_coverage}}
\item{\url{http://pytest.readthedocs.io/en/reorganize-docs/new-docs/user/pytest_raises.html}}
\end{itemize}
\end{frame}
\end{document}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment