From f72c9143ecee2c3645719a91670ba49d2cb8530c Mon Sep 17 00:00:00 2001 From: Kraig Brockschmidt Date: Wed, 30 Jan 2019 15:13:17 -0800 Subject: [PATCH] Update unit testing article, adding pytest --- .../discovery-failed-status-bar.png | Bin 0 -> 1022 bytes .../discovery-succeeded-status-bar.png | Bin 0 -> 717 bytes .../unit-testing/editor-adornments-pytest.png | Bin 0 -> 9183 bytes .../editor-adornments-unittest.png | Bin 0 -> 14789 bytes .../images/unit-testing/editor-adornments.png | Bin 17359 -> 0 bytes .../images/unit-testing/install-framework.png | Bin 0 -> 3254 bytes .../unit-testing/python-test-log-output.png | Bin 23772 -> 14424 bytes .../python-test-problems-output.png | Bin 0 -> 7361 bytes .../unit-testing/result-adornments-pytest.png | Bin 0 -> 9895 bytes .../result-adornments-unittest.png | Bin 0 -> 15703 bytes .../images/unit-testing/result-adornments.png | Bin 8005 -> 0 bytes .../unit-testing/run-test-adornment.png | Bin 3600 -> 0 bytes .../unit-testing/status-bar-run-tests.png | Bin 1290 -> 0 bytes docs/python/unit-testing.md | 221 +++++++++++++----- 14 files changed, 160 insertions(+), 61 deletions(-) create mode 100644 docs/python/images/unit-testing/discovery-failed-status-bar.png create mode 100644 docs/python/images/unit-testing/discovery-succeeded-status-bar.png create mode 100644 docs/python/images/unit-testing/editor-adornments-pytest.png create mode 100644 docs/python/images/unit-testing/editor-adornments-unittest.png delete mode 100644 docs/python/images/unit-testing/editor-adornments.png create mode 100644 docs/python/images/unit-testing/install-framework.png create mode 100644 docs/python/images/unit-testing/python-test-problems-output.png create mode 100644 docs/python/images/unit-testing/result-adornments-pytest.png create mode 100644 docs/python/images/unit-testing/result-adornments-unittest.png delete mode 100644 docs/python/images/unit-testing/result-adornments.png delete mode 100644 docs/python/images/unit-testing/run-test-adornment.png delete mode 100644 docs/python/images/unit-testing/status-bar-run-tests.png diff --git a/docs/python/images/unit-testing/discovery-failed-status-bar.png b/docs/python/images/unit-testing/discovery-failed-status-bar.png new file mode 100644 index 0000000000000000000000000000000000000000..bc4ef59d2d419667a9b9256cdd48f36987084da1 GIT binary patch literal 1022 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02y>eSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E;2FkAZe8V00VAGL_t(&L+zG3XcSQthF9YQ;}bzGVj&_T z_DX6&(gT#7a;Cf(lVVQdy)(AQmDjq!1Ald_*ia0SSm8(Lxd=NhJa+q$ z2I1``+1)cZ`gvESy8QOYA@@_HL3n#fdR`wdl~*h-<|gMiAH8$a{TgWm-cIH~fA9G0 zR!oaL8{6*$q(6UH8uE5>r_=leNXLwbmXx}|=s?i2`{~4kD__5Fy87ZY7SQ181R-iL z1#c&FfAnCrx=dsER$O!L(Rrs4Xy(II8!C4DNni|N+m=7=r-7j0)O)dM13PxFdum}L z=7gZSv-0D6*I$0+lq3#}G-qI#%JZ>(e6Z}mishBphE6##aRWnRa)*fq<_c>W0UG^^ zuyCY{mEk%vv4_4IElhgx)KnFq09TsKLV<1zxHF(+%+4c5x>BWOuFz`rc0BSzZP$lR zDm68llNQ#6i6{#jOu^grxcKDkLTNRVA*el?kJD}Ky#r1UpwYl|#M;zh326kgP{zi% zrqUh+!M=?N4O}QdM*O2-jZGe?D$x#LRW?_sr;=D-BALq5B21LjU<%$2;HNyt1Kxev zfj_h9g$*>5KJisL%aS`l>3|FA(Tp_#dcY>!X|hQysAO0`fzE|u>cjYwp)lOhl-b%K zv!SdW?Wh=nfY58LAU2T}brazlHkg991N13R+`vHHPkhv&fpOsk0Oj&!#kD zSS2)wfE_0W5Zi$A;zDM4OgdtkjN_sa#^C}k%+AOPqD7b}slgPyT?@i}n%Sn=00hM* ziqH-|9iP5$4;?ip^uWeKRHaT(Fbg-)uzMv+#uMSch;0~}@Ri6l3PTW{l$8+%)DHBl z-)abav5y7vasdsZVP8SC2oohWn1Z)!x%;NWe#(Qw&sFoq)^erAZer)m!wc5Y4vdvi z$)ZsiP3-I7tV!UG2Z&zoqk|nXi0#?#D2twBz+&vtNJdA*fdJPey@1%x3GTQ;Y=hWn zE)jO>Hkg99Yw61$nfb8};g)7%c1!2rCFlEpfPv}G%LLwz)PhF=kBEKln~b+3zv0Ue s?+?DvvVylG8OPg^jN|P{mgyS)1;?{Vg1_Fk)c^nh07*qoM6N<$f?=lK5C8xG literal 0 HcmV?d00001 diff --git a/docs/python/images/unit-testing/discovery-succeeded-status-bar.png b/docs/python/images/unit-testing/discovery-succeeded-status-bar.png new file mode 100644 index 0000000000000000000000000000000000000000..673a7fc9b2694012c98cbe988dc8ee70c51efd58 GIT binary patch literal 717 zcmV;;0y6!HP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02y>eSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E;2FkAZe8V00KQpL_t(oN9~qBNLEo8#=jt^P--dC&7ro& zD2I@iz@9``+`*9WPOSoZH5%6F2%bLAVNIU_~nL0gy#JiBfkAUW__~m z=!%J3fuF$~yfKH@wS2j0~L|p*snRU<%WBPgi_B;bptS_w*HkHjFgeQs-J{2P6qIws6Ciqw+xd8HP zIRs^1;q&(sNiJju)ur%_ zoP2XJ`!0a$QW_sU^gA%isLm~_bBpSH(lxscCdV}(Wd!O%00000NkvXXu0mjfv|&Y$ literal 0 HcmV?d00001 diff --git a/docs/python/images/unit-testing/editor-adornments-pytest.png b/docs/python/images/unit-testing/editor-adornments-pytest.png new file mode 100644 index 0000000000000000000000000000000000000000..94c044510b8d1155e37f2c36644813078f7bd9eb GIT binary patch literal 9183 zcmch7bx>RD+btS2xCUAhtU!?h2`x_0KyfSX60DRWg<>s%gFBSsL5q8V8c<4GplEO} z6nA&I={dh|dcK)EcdpFbKO+0td!F~%@~n5Q_3lV*O%)(1h!h702dIir)WyNUeTn_Q zLyU+0&aAuH!v5fT>Z-`&RQ0j0VK)dI;TmupoZ5J@OKU>xHpvr&u_q1=#h2e7-0$us zcGw`Zmy(f}p1XtBGwY}JI8Usd9(xHsw)X-<1@8%p2=9TNQgLuNv{V)0`o0!h*<10q zzNUUVVKZh){>%iJdeBG*y!Ij*1&wG$v?pTWXnG{SFL$t zxKwY%{6wm1UGnzzIv*s|D;$G{+4VH96(7~P#;BSY8=ae$z-`s)G!6Y(Rqv8L3?_pi z)m2BkoZ~s1?5)?_^8m5DT@uDy9-Ni@{8s|QXkjknJLS@Gg{fghtzjT&G3SQe+wX}D zbv1`g+Nf_ScG(rj50VTSUR^Ud54=vQNFKSZg6VF@%*g{mdP&}OlfMxE$AgaL!S7E$ z`7vEpNg2F$-0HXZ4Ol;l_)GCm(LeZL$gTG*vd?zMtAb7ZR%L?@pWPhw&5m9Bf4Oxs zE+#_$ub~Y~;Tw>r9OQVd`_J^I8A8A7UeUmfng4$t&`t|?12w;Uwrvb}q?h}560GAtdC3>kD6aD7EFaneCw+Hv!YyvtHUsUjMIY~>PIvI{^f}A{ts`zc z<>=6goj#Uf_#!u2!RNGP!Dl}#tIXcnRN+oX)e+jmp&r+0!*B!$?JSHIY9 zPFG}ai~%nxLoNir^*&%K6&aJ0NszF$zr*`-`||LOEKJ0XfY^Y^%`@&_ch*i@6c{qf zG&AA9zU7~0A^IV&fBUA}@wPw3O5LZqkG>l#KBi+#F*X1ZJiDr^<<7$QKKkG<^S=(H zaQj+su6AO5)8jB~H(|=)I%qyA;pbqF%4LruXLc?eTefP!zioAAlye)C1U?03i)YP+8SA|y~$(?LpW{dQ6!%Q*Z z2K>yOF+-5xH{;wpeWBjOr_T

rc)WngnOC5AyV0kwPPc=qY`aRh4j-)+Ryf=$`c(VpesYW=I@mG^A!? zPwfthNy}?Ej@sh+&$Wy8p`My$BmDVi2mJi@gvO0(KoOz5Jh;EbrC1{433U1}yJ)XW=N_A@*S0i$jt=s8xbaV|PM;XG9 z9v*wEg9Vt^YsmPB5>*-m5fwC`Ha*^{7X{K^6O_2@I#+*0<{MT6vk zB(Gk3kn`MH(MjKyMSZ{k)LiBhq4K;_bZy$xOZG;&D9S#W#~L`J(cgQIdE7{)F@LeP z8*erQEP9=c@EjlI4|BG@EoHBUPu0d^sO^#`O-F#`RM!``XZ7sWxrG4Pfe&nZ@}9~l z4t&)TAz%gz8o)cq3xE#7%{AluZB?2hC0sy}7!wq^nxPF4gF!1QIz`PjBBXVdIoP^; z*AlmF6xLks7^p>FQuUs|JFoOnF9wOcw^HQ|oXb&3pcVdOI6L|f$>5J@-ilXaN}Q)( zgc3X1V${t)aMF#bsQ|X<8b;{~`GCk|T7S0OaT_+ym0}wI-CGa`31Mc%4a5;Oy{oPTHMqR773eoK{ws6?TQT69jQXFgw_$JXuOfrMyfEhD4x*1IP?) z--@tkhdb%5SL6XE&XGoM0j1KKcIq&Mw~&YkuswA+9#;|m5l|Y<^lO;^m`a=Ne34jt z|B;uX1`s0|!Q)#5DD9%VrBB7Hjt@n2sYtD^LlGv1Z{S}YSyjAKgdu9N08wTf1z(ra zs??jO)RO$CURVf*84RU5=I{$jVN=4gs}a)ggicr~&pQg1?_`n#vWI$+z#^zHT*F{_M4C2=7-BB}Cn(@F(9_eCrx4yFJ8WcT z)?g^#IXsjE5I{b$4k|5w#~qsR3W^8`q-v56rNaL^jhoBB<>lq-&52BC!t6j90R9{- zmjE%n6RIw~<&;1TZi(d%MVMf~q*M^jhYvvw&CST52c2z?un80%V(|!K{0E=xXrRdB zzut!5clY)GUTiu0;fRtl;IE?I5XYeTJ`LY%Bf<~2L!o(dAZWc$Z}+IFZ2DXdC*a`) zVfl-?;&L^oVnoXDg+rTnCV>#2;WE27;v3ITy5 z;DCYPz+4HxtILDjpw(q9>Gbx}3*_a)J6bAcDVF7Gbb7;6}e zsOwo4@?wSy(?AV%M~3zI`8csGzk}@{V_Hb+p%%))-N?m4{(x94$I84$!iXbCPkDVn z7AW!24_{`%eP`Tm!|w84bxEymqb5T9Y6yIA7WDYnbJHCn|G0pQ&fET<)EZ?!Je?6X zS@`)avsRgLdvT7|?%wYMQ4#N|=M9nohB-5jx5~j3MWxJ?HpvG)PE@W*aC~wDR8lSd zTbr>=0z)E~(9}9_`R=t`!2Fk3o4eGV@d@9#Oa>B`{pQqBp&CCdMpDAd;Bm$ArN^Az zX^{yLkt67Y`9yJjuj4J9NXuH12tCaa-Djb~U{|CNLCn!N?HZ*5dVpwUkkks3QX)N@ z+?+!s2CZ<}W5(zb?J%E7E zIS}(Q-eJ4+E*h`qOxgf{)D>L2>z2egZOu10*e{3Xsxqw$)?>C zqTiixu(4F5JgSJ``ZWBzy&4~0hBBZXbf}oZ40`Q1Hg_ zy0%!Y6@3o{@kaa2JDgH2OBnG_)MFn79&EQ9_PA|$T8<|VhB(IEakr2!uu|fYE2Nel z1-}5^lutSI-gSQUn9LB@MQ4Zj_;i9&=DqKliZ=F`y16ulu0z0^lcFN-H zD~F>i^}^GIoEU1J8wrrte)oy&^#i`KzMZFTLXyAI4~Qy&tPg^}NoKlMkR~m)VPG3) zbqL48`v8e2Ttg|$`Wicv7+kjXsNDP{l8w!n)u64*q`1p{RZq)V*=L!P!D+44pr-Vk zc7h4+A|t6c8e&)o-rU@r{}R5kyzClSVx@P`8GYySEiEH2R4rzE!bRw#$=d#WBd%;$ z+QkR+rN$qssYRO9Dbl(`DhGkupl)P1v%dKS`52x))39@RWAp@HQO!9`$SU!Z0R^Ka zHOcNNXcFUjesp8ntV0;V5=$vOS<4?3`l&x+mdLoV_2_5%!={O-0r0q`-v+lE!F_?C zRqwKE8ANi|-FoU8`ZaWtSUHTV%NVYS3Lr>5GgKSyuB#pE2H6Pj%`7j3X@JwThjRVk#-4MSzq3yt6x@pD;%*+I!Q~teXHu zcb*E86i!D%7!2{wuaf#fV5D~6U_&{qWK%5DdEmvP{?regBBfqv_=AY~2Y)G~W7CiV zX)e&OA;^Sr@S+Zh)NX<I`L2;Yi1uEQrL~qD~~AKA5&J<2@)PBAcTeE`jg>*@N_bGM7O5PcsA96iFKj z;n((5Od}WIpYi5GIWNdbJR)c1Sh6wDA@E}Qg_znVnSRi@LX?JlY8GJu2P3BnE5X+e z-VrcbWbVu~_agvTK%sAitb!Q|^>otO(-C?9=t^v{|!b4P~#C!RPPsa`_GoU+-j$&!qks z+^lhf*cT;EXJI~14y#)sBCn`l?sR;?$_b(wNiRR2=hH3LdK z#dh$47OSR`mQaZ)om=rrKcdF3kydme`C@7gvhXRyf3>xQHrE^MQJ}{wtk-S z`p1LDr)TSACuQZOgWyt0EZ%x7%SUSIeq(YE_}I#r_#lK2j#BG0F2I0~N_#oANOXFr z6wSXPh3u;|Ls$o~R^v%3X1vRdCFNO6E;{PfwJ~DpUU7@IVrt>C_GmW|x}&p94$S6q zikL|U0h4Y}3jG7Y$rDIeiB0*!fY1vOT|CEf4*L+yO91Sm?GaL25Mf9ONCZT$=jk#? zx(KDCMc)L!>WItlfc(mE{E4q!ZEKj*NdGYV4Ir0ksGuWDDM)(d;bY5DkQ*|gu=)bb zMZ5heezwo9&$2rwk)}w)P=$};F&BvQd!@?0j^IPEclyIz{_Y6?jO_#$o}#A;QoQ2& zeHx6ZN!Zgc-KX^$#K=ChiT<1%wFW7B)lu3u#2DoyThfnsU3>!1k!el#Au1`-dvhg& z*hst!=U+^-slCU`ysxp4?G*`7%2Nx3a(}?*PUoXRjIeS=&F{55>5w}Ei$rC`steer zz2XUJhbnu<@=c7_EbTx<;fw-TdJtPvTd1$TPAG*{2LXh&&Np;o%718n*CG;& z0`Y$W{}KaOyuxaGmH69lZ_K<2Zmd$NFnW_i=<1-Oa#2yyMonS}mZtreq2Q#2y1YPR zh5W>X@su2K`eQ7|?`m(yvyY&%S(QW8+>r=4y@yo@c$1^x1KBgI*Yh{w4?RfpV*_lCpJEO8vyUec`NN>Y#Ke#Ps&q>$! zH6~J{RIaAK9rlcSQ}##CJ&8JyOB3Xf$NJ$2mQh4d6}~Im4)8ByR`&H#Qa3| z5zwM)P-u4R1n$-8_LRHD4_mqKRwOl44);40n4J_YVMuHN4n&H$All!-(4tyydFO$L zz>H7Um3}0>9OFhWm)i2JoK7{EOSObxtGmm<(~8zlw#k(zFQipk0`1~IS#V9|n!np- z;`shC{~O+f1O&BO1W2bm_hcEHdauOgWVJN0HQGYDpq-Ji2No0W&jNhrW`?$D!+4lY zb?zRcRavKfMPDtqXG@=Ny!28Rf^}YkZRTBk7gaic(FhvdkSy2c^ocol{ltd9kCn6;h9@W<(&9`?~4A-N()MP#G9v~FB751Wb zmWi|x+0brPJQBacTEJ7cfWJD$uLJUm$W7m{aU0|h@GLTVRY3vq<2FF4x4-|9Ae@&^ zt7aCi$PjT)#C)d6wUJneq$dnFs*$SNt_G11qd>={uZS}ve4jU=IdXMfx4|S-k9io3 zi69vQUp;G(FQn+nW8l*XqEGIn(iPN{Io(jJwN&LCgD2G*>-p4-uM$P&H>)i~J0Bm* z)Ad6EVz3(xNL0oO&K_BVPaIb(iJg?` zP7+4}3&_R$itHDp=F%SBYphKjFO`l>Op{7hGmI9VC?$4M_$*F5xjQ@KzwX|9d2iP2 z!e7`!@*8NGDl4Xva~i}?`U*g1w-HL7pZ1ReKr;p@dt@ap49IN7#wmTqSiQuG062Eo zSC4bQ1((-45BC*Se(sI0vHhbb1Yz@{vJB?e3*YFsD_!D5% zA`uqORKDI*{4(2Y+tclHGs4_hlh56&9b-fbfvuJU=4o&0&DWboE?291Q}X&g(^z5q z&WKKs=y&fBPfObdr`^3i-|EkE#ryo_z9g8RC^+}NlUh7h1JJtv(Ewyv4WRQB6Ul-ZRb4Nwe>j9OUl zLPNo3=>6M=P43NJV-B7YwoZ9Jb$-44RlCwcIOTmkc~YI#kV?R#$tSLsBJ<#)xiYad zp9`3go-U3hp94j2LZ&P(zoMeG#?{1OGf)FRgUk_t_}TvVu~!u1-KTm%naqTkHck2r zHLSaNc6Me+uo~%BeYub*+DPmn?xFRKI3@TNP{MENf-RUe)n(<`yT-Kay&gXZ4N+h2 zULQA0c}NNvMGVwsejNLV-JFlY`Rhg-=IyX7Ex}B6w&nZ$7@=I~$C%$DCj*Le;;+0Ajb09+oZT@^v%&!$;rEW!pLU&# zeuPf}E;%i?cYIQ(1n(HUYH^)PoiSH|P7rmyP*&^VN}5(fMJ=@w{e z?)h#{(Uhwal4`U1qj$1cNG5~qp@cy&TVdB?>ICt4l$W+@=14};Vh@!+04VW9iB!X` zU&%0O{+XbRgG>a5noGS8>q1VrNd(6-@+)<@8L~C|vSzAH4uM-wRLc|!)KSM4Q74kt z)m~R1eW_;zM5&jPOg=(YodIDi=E1-(ABnB==2#u7z(z626o`Ca|BtuXbXXJYdF zK5-R*)PIKOA44ZiEn*b~nhS_GPL$4wDWC?&%KCir#S`J|;Chbl=A|~Ij!JMmm*g;L zZ;@MiBU?Dmso!OMPvR+j-?u+ai~S2K1xeUNsFS|4>BEvV2F4Cn21jp-J%l3EE&6H} zpsz;mI1eli2G%w(>qf+WyX*ixW;!DDgf7CpAIkoc=1eK`i`^@Jk@tL z!{pDrYxfkodbW}~Cr7--^0zIho&lI3g%sZT4^7D6A8wlExcJ5oOM$$r1aZ5wClZ*8LDSjG3T>zhIIWR^8Y5IE48#914CXPlKP=T<^9>+d^4T_ak-1SsO1T>TaK+;JPM{uzpfSq}^#>P{ z7bnKQGGOuBt(#le6~O{>nyjX*=PO0`(*l#JZ`n8GRJFY!J*pk+)Do>DFqoq&3Tygi zzEAAPtZbjh6(z7)^lmk=&xTLKCX@46AeAc>Bji_|)OSz;>7llQdJST=S&v*P4>dSN?Q$KEIlVhTf-#3oH>eeGjEO@MX= zHz+8Xt2R03zh-COWOw`c2r&ohc*m&h%w#%o#TwWXKsAqinr;A?WI zjKH6Fp*)P7wrBMOK9D`w@{C?s5)#q9z(((yvjDGoCcAg!er~ zS`16BsEqiF7vSzvPGJ5u$X?j{R-d;k6U%Z8j7`xvRrso&v(a5pe{qp3Qt#y(A-bU; z?cBtB8W-RL4*7y9f|rB;8%lxi7UzGILi%Ow?tfDX@yWdx7E*CfAc*9@l>)6|x_;}S zR#=Q%Y@K)&k35lZ%f4DMtp&jTLZY^1 zn8=4>rx1`LD<8dxx`&V19a#S(s`6tkYuk=OCoIRe{JZl-#D6;k9RJgmf-R?kg@px@ z@0XV!-_pnzXTE|Wt*voEc2y9$A3uK7*Vh-T5vMy~MFBCDU8h-pZ|^OcfY;b`xB^a8 z$1=;rVxpp+s{@eMJM5wA;@DW*HzJjLJc)Bu)ba@b3v_`>`~scB?-v+cBV1V^c2Q0W zsGhSQ?!htSd*#CN#Ms-mcw*zAWmguO;8Y9*;$fW@G!C`A6gCwk)b7u6=RdB;AFTUZ nWBgwQYq8ZsW}Y0a-{4!bTgaF?#=BzQzrj&e(p0RHw+i_m#N|A; literal 0 HcmV?d00001 diff --git a/docs/python/images/unit-testing/editor-adornments-unittest.png b/docs/python/images/unit-testing/editor-adornments-unittest.png new file mode 100644 index 0000000000000000000000000000000000000000..839ec3f436bb627daa62d229c3fc68442e384997 GIT binary patch literal 14789 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 literal 0 HcmV?d00001 diff --git a/docs/python/images/unit-testing/editor-adornments.png b/docs/python/images/unit-testing/editor-adornments.png deleted file mode 100644 index b6bbbebf112fcf39123ff13207eae635d541a382..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17359 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 diff --git a/docs/python/images/unit-testing/install-framework.png b/docs/python/images/unit-testing/install-framework.png new file mode 100644 index 0000000000000000000000000000000000000000..e7c071deab3abeb0dc5d6094beec4388fc9423db GIT binary patch literal 3254 zcmeHJc`zH?7LRK2Ra07NRobZKt8^i%qRWR;(M3^eDY3LjQv?kO4V8~t8d@4#EhRpp zRf&o%tgfi4tzy?!v+Jts>SN2>sc-x18d@qlMfJVI z91iF8+lI!*#wISWt*vd4&lmRa1;P&l!lAz5nW2eqV`F2((+gAcOXB$--0(hKK~(589DM;<6drZR_F8N(6xruZolExfBL-|HJZiw+jn=qa$D zUUgs-RNgTw4hzIU16Y;t`<_9rZ0%UPw_!t-#RS%2sv52>XReDO1x z{dDeAg5=VOuR3DB#A@{mQ_}q5;B*4lEE4E(WM)kijG)kM9qgtGbBdZ= z+~n?)X7eXQ6HA`Zsrp|syN8z9bx{=3l*D>jYv764`2}E6Ma!eQ=r6gFQ5E@e$s{O^ z%7Db*Pbjm^$~I}pjLzwt{U$XW=!9Uif3JWNUPObB*6{SEF}gmPdG5H!gybF;&xO{F zGVLu5R$m*F7Tpvop#q0{j_FZcx-wsPITZrS44AsbSKVW_l(OrCbBOQ4o@3~Bd7rm5 zqGw4*v2Qgkb@N3J;qKWxfR*cR?w4psMnS6-Bs49R__D;9Pfjy09P@_iyvbk@1* zZFEu-`a2VdL27d$4_=u{TP$4o7#&Jrs>IaV$I426L0fkx{} zAGh2$8#?Wt{bpUGkkp;HXBM8*-D&TT5*=Ww>6i=BIhB$-clss$nHq(PZQrh=qk|3f zpf*vOTopl=s|8PeI0X+##YeFPU;;GS93f z;BB&!+Vh{g`=I=S&}ddtcxW_JiK@Zsn z|0|eP?EX1yB20fpFRWSk5d&RZC2U|Xi3xLizN1#qCIQk8ip0|dX+BSp2UtAoBAWYz z>402I^sz+17-K)pq_0=)E_5vOSb4`!B;S6YbhSA5TRE|Q$U*oaO%lL>FvWf^a znTSo6y2(jd4fUQgqmB;0+_=~GroJOrB;Z!KPBriN>eQD=&tU4t<7IrPsufY{ISl3< z0eU=2AlHLn#yJfb{>;w2Qr_Y16)L90ZKtXpf_P4)49sotUgJ#;9-b^RXNabkxsn-?AMjF140TE>HVu zPWq6N9 zcy@2+wN5-Jm4tCR%8mAzYuk7@F5kyRUE!dzxNa3z&xD?%#TeAFnj6X>LKL_>Bh29R zXjGB$D`TloCl)6-LokZs6TVQXN!U6{e?w@%QL9#yv=iUNxy&$BCq}gV(?T55RzksY zo4**GG-;^U6YjsO8q)Y7ff%vl`q#TN2JxD)pQkTw+SA580-wD9pJSNhztxd!Cb1+? f-F<#h94=we_HDbDbvx}>e`$99ifOTlTjbvWJ!@OA literal 0 HcmV?d00001 diff --git a/docs/python/images/unit-testing/python-test-log-output.png b/docs/python/images/unit-testing/python-test-log-output.png index 3d4deef576283bf154f7e9f7ecb299c582fdb1eb..c9bc1ec9b055074f56dc09d5f4e34bb9012779a3 100644 GIT binary patch literal 14424 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 diff --git a/docs/python/images/unit-testing/python-test-problems-output.png b/docs/python/images/unit-testing/python-test-problems-output.png new file mode 100644 index 0000000000000000000000000000000000000000..62514d480b4ff3d99cbc2bfc90c77aea8c574cc9 GIT binary patch literal 7361 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 G5&s2O8H(Wm literal 0 HcmV?d00001 diff --git a/docs/python/images/unit-testing/result-adornments-pytest.png b/docs/python/images/unit-testing/result-adornments-pytest.png new file mode 100644 index 0000000000000000000000000000000000000000..b1a47a8a5e666d99075f4cab3f8e60164fa597bf GIT binary patch literal 9895 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 literal 0 HcmV?d00001 diff --git a/docs/python/images/unit-testing/result-adornments-unittest.png b/docs/python/images/unit-testing/result-adornments-unittest.png new file mode 100644 index 0000000000000000000000000000000000000000..079931ce940f1134bc1ffbced37d0ab265d33092 GIT binary patch literal 15703 zcmch81yGw^w{9qHDYQ700>!O(ixf(5m*P-76n7{=0t72s+`YJaanc}dDaG9(KyeRF zaBlkj-+#`3?wSA0ow;`|GZ~Us_Ph7H*Is))&$CvTnu;7Q4h0SX0Kip{m(~CPFiy}P zqeu79N4$z3U7`PBxM;{p0;&d|Z=rwOw~|nn003%Y9$%Y0K>x=6Ag|{F0N{1}`CxQ8 zm6)RslDo?2x@tOExQ2v%eVQ=;FYJu(BrAfSSE{|2h-mrwxHkXU9{G1rP#?VHB^fJ%THhpTRX*DFlRqu} zq-V8ak$opqc9|NX{R6f)T|X0}kDbGnWI98^+HJ0S&)VK zG|xqHAF&B0Wz>oAJg>;HC-lk(HSc#!4FLELeg`k&>32?68tk`0pWBoW;f9k_13~}{ zDE=Jn$ml8=Nl8gI`B*4Bwk#nwHa6@3=dV6}H%*fjdT`HW&1|UY^+=Z-@-mV2!2nSt zJrNO+M(kzs)lZt+!<)O?^Qt<((~G<7!K$hD_ATCaC-)~bcLpXr^YqVT7#SH0Xiqs& zJ(zx%Y1NzwlM2X0>sv>6M%vahQa^Y1GqU#cPUG7(<8*J*mZM(w_RERt+s&BUPmMYR z#?+uUnwpwU?KfxB)2V}_4=qa7tTgZEe+mi;A}J7EZQEKB^Y{(BD;SI3FrG|64Z!aX zkZCh+*|$cTtXQj{C#BaZ?bmCIH}i{eli0I49Hi;<*a7O&==X}Fp$DsOwVLbiyVD+; zw7AS{9r8XKYLkPP1eB)d@?YMO++9}Rm95D;Y!SiVOKxAER{K@%cwfye7Wuh75K5-s z6nZLzI7`O6z8LaTaeKkjgPMmdPB`0}-+Yy%p27&rzS*_9IM-56neML7RkBVIM!ch~ zKP**mRT5B4vS@O{I&sG#x{UEXVc3H>xc6%0&ScX5{kGz~6?=TfI*g}J$;4TrZ?riFukRO?#gKe<&E}c{F{^Lm+}|q{Dox|3GR;?jCDgi^ zw^rgeDcce5=%mn!Y7c`N*Mjy6WT_oQ zl&{r3uev4Nxyh^2k>b(N^b4@7-hfE%DQ#l_+rP-{~T)h&F zhAgs?cXI2*X`6#_a+l9)>KMi2i~rBQx7RwAR9&6yFNpBMJyA6A12#DAD;FuJ*O{Y5 zp?BZ3dg<0wF6(gcXq9Xw1UMkGjRAN$LiH)zeI1+Gs?*9kWM! zke1x=prHC*=`(hA$iR7i%+Aau+Q9G7R;)^Wu35+Mk)K0?Qa?qAy=E}!XuvGEynM?6 zyxF^|qDCd@gf*SNx>S2G)qdL$t*QqfR#nS&_{wtrf)TxRsKQ9bvk?M5>!{OEgw2tt z=fP@Y@onHtoVe03mvijt$-PGsugCSr_2zKdiYuNran)G!kAcE3knsKF&#)bbxu8fV zOd^tmfX&v|l+RU|M$g4=wp86L<_ILgVhL zal1vYqfo_~GDsYLQXbtiCH^v89{newABLcmQaQ%%O{bC)|A;8fb`L9J{(G^Es`dG# zhV>e8Z}A<_llf`tX}j&9q49Ey>1oVbNvSq&_dUG^B|HH5^YF2uf`fzeMUMdHsNKwJ(XTl34XP>FXDH4xwgVwr@@AO5Af_IZjX<>{qDh1hpO=5{TqWi1ZA-$ zOztE4>79IxD4(mdxUn$(wYH7JCcn31?utXtd1T5CGP{h|wuD*FbDdzV^*8-=&~9Li zpM*BcIKr3(Mf{BnBzDrVFI>NV!0RrMmQH#=?5%$l1N@$HW&I$;PVw zJa>&q0Hxe>`a({Iw4(r8fWP}lEP~&y�sAY^~~ZpSz{rTv#KC2$?OnOT*ifZ31FN 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 ptne2=H}Sp8>ul)DVEt9*7e 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 M85QX&$@c;O3+jaANdN!< literal 0 HcmV?d00001 diff --git a/docs/python/images/unit-testing/result-adornments.png b/docs/python/images/unit-testing/result-adornments.png deleted file mode 100644 index 4a2a741a45724bca5205cf50a792cac440a89a22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8005 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 A#Q*>R diff --git a/docs/python/unit-testing.md b/docs/python/unit-testing.md index a793fcc5a8..f6fac53b56 100644 --- a/docs/python/unit-testing.md +++ b/docs/python/unit-testing.md @@ -4,88 +4,89 @@ Area: python TOCTitle: Unit Testing ContentId: 9480bef3-4dfc-4671-a454-b9252567bc60 PageTitle: Unit Testing Python in Visual Studio Code -DateApproved: 11/19/2018 +DateApproved: 01/30/2019 MetaDescription: Unit Testing Python in Visual Studio Code MetaSocialImage: images/tutorial/social.png --- # Python unit tests in Visual Studio Code -The Python extension supports unit testing with Python's built-in [unittest](https://docs.python.org/3/library/unittest.html) framework as well as [pytest](https://docs.pytest.org/en/latest/) and [Nose](https://nose.readthedocs.io/en/latest/). To use either pytest and Nose, they must be installed into the current Python environment (the one identified in the `pythonPath` setting, see [Environments](/docs/python/environments.md)). +The Python extension supports unit testing with Python's built-in [unittest](https://docs.python.org/3/library/unittest.html) framework as well as [pytest](https://docs.pytest.org/en/latest/). [Nose](https://nose.readthedocs.io/en/latest/) is also supported, although the framework itself is in maintenance mode. -After [enabling a test framework](#enable-a-test-framework), use the **Python: Discover Unit Tests** command to scan the project for tests according to the discovery patterns of the currently selected test framework (see [Test discovery](#test-discovery). Once discovered, Visual Studio Code provides a variety of means to run tests (see [Run tests](#run-tests)) and debug tests (see [Debug tests](#debug-tests)). VS Code displays unit test output in the **Python Test Log** panel, including errors caused when a test framework is not installed. +After [enabling a test framework](#enable-a-test-framework), use the **Python: Discover Unit Tests** command to [scan the project for tests](#test-discovery) according to the discovery patterns of the currently selected test framework. Once discovered, Visual Studio Code provides a variety of means to [run tests](#run-tests) and [debug tests](#debug-tests). VS Code displays unit test output in the **Python Test Log** panel, including errors caused when a test framework is not installed. With PyTest, failed tests also appear in the **Problems** panel. -> **Tip**: a useful repository containing a variety of unit tests, applied to different sorting algorithms, is [https://github.com/gwtw/py-sorting](https://github.com/gwtw/py-sorting). +## A little background on unit testing -For a general background on unit testing, see [Unit Testing](https://wikipedia.org/wiki/Unit_testing) on Wikipedia. +(If you're already familiar with unit testing, you can skip to the [walkthroughs](#example-test-walkthroughs).) -## An example test and walkthrough +A *unit* is a specific piece of code to be tested, such as a function or a class. *Unit tests* are then other pieces of code that specifically exercise the code unit with a full range of different inputs, including boundary and edge cases. -Python tests are Python classes that are saved in separate files from the code being tested. How you write tests and how you save test files depends on the conventions of the framework you're using. Once you've written tests and have enabled a test framework, VS Code locates those tests and provides you with various commands to run and debug them. +For example, say you have a function to validate the format of an account number that a user enters in a web form: -The following steps give you a quick walkthrough of working with tests in VS Code. The sections that follow then go into more detail about test discovery, running tests, and debugging tests. +```python +def validate_account_number_format(account_string): + # Return false if invalid, true if valid + # ... +``` -1. Enable the unittest framework by adding the following entries to your user (or workspace) settings. We recommend explicitly enabling one framework and disabling the others as shown here: +Unit tests are concerned only with the unit's *interface*—its arguments and return values—not with its implementation (which is why no code is shown here in the function body; often you'd be using other well-tested libraries to help implement the function). In this example, the function accepts any string and returns true if that string contains a properly formatted account number, false otherwise. - ```json - "python.unitTest.unittestEnabled": true, - "python.unitTest.pyTestEnabled": false, - "python.unitTest.nosetestsEnabled": false, - ``` +To thoroughly test this function, you want to throw at it every conceivable input: valid strings, mistyped strings (off by one or two characters, or containing invalid characters), strings that are too short or too long, blank strings, null arguments, strings containing control characters (non-text codes), string containing HTML, strings containing injection attacks (such as SQL commands or JavaScript code), and so on. It's especially important to test security cases like injection attacks if the validated string is later used in database queries or displayed in the app's UI. -1. Create a file named `inc_dec.py` with the following code to be tested: +For each input, you then define the function's expected return value (or values). In this example, again, the function should return true for only properly formatted strings. (Whether the number itself is a real account is a different matter that would be handled elsewhere through a database query.) - ```python - def increment(x): - return x + 1 - - def decrement(x): - return x - 1 - ``` +With all the arguments and expected return values in hand, you now write the tests themselves, which are simply pieces of code that call the function with a particular input, then compare the actual return value with the expected return value (this comparison is called an *assertion*): -1. Create a file named `test1.py` that contains a test class with two test methods, one of which is intentionally set to fail for the purposes of demonstration: +```python +# Import the code to be tested +import validator - ```python - import unittest - import inc_dec +# Import the unit test framework (this is a hypothetical module) +import test_framework - class Test_TestIncrementDecrement(unittest.TestCase): - def test_increment(self): - self.assertEqual(inc_dec.increment(3), 4) +# This is a generalized example, not specific to a test framework +class Test_TestAccountValidator(test_framework.TestBaseClass): + def test_validator_valid_string(): + # The exact assertion call depends on the framework as well + assert(validate_account_number_format("1234567890"), true) - def test_decrement(self): - self.assertEqual(inc_dec.decrement(3), 4) + # ... - if __name__ == '__main__': - unittest.main() - ``` + def test_validator_blank_string(): + # The exact assertion call depends on the framework as well + assert(validate_account_number_format(""), false) -1. When using unittest, VS Code by default looks for tests whenever you save a recognized test file. The unittest framework specifically looks for files with "test" anywhere in the filename, as in `test1.py`. Once VS Code recognizes tests, it provides several ways to run those tests as shown later in [Running tests](#running-tests). The most obvious means are CodeLens adornments that appear directly in the editor and allow you to easily run a single test method or a test class: + # ... - ![Test adornments that appear in the VS Code editor for unit test code](images/unit-testing/editor-adornments.png) + def test_validator_sql_injection(): + # The exact assertion call depends on the framework as well + assert(validate_account_number_format("drop database master"), false) - > **Note**: At present, the Python extension doesn't provide a setting to turn the adornments on or off. To suggest a different behavior, file an issue on the [vscode-python repository](https://github.com/Microsoft/vscode-python/issues). + # ... tests for all other cases +``` -1. For this walkthrough, select **Run Test** above the **class** to run all the tests in the class. +The exact structure of the code depends on the unit test framework you're using, and specific examples are provided later in this article. In any case, as you can see, each test is very simple: invoke the function with an argument and assert the expected return value. - ![Run test adornments on a unit test class](images/unit-testing/run-test-adornment.png) +The combined results of all the tests is your test report, which tells you whether the function (the unit), is behaving as expected across all test cases. That is, when a unit passes all of its tests, you can be confident that it's functioning properly. (The practice of *test-driven development* is where you actually write the tests first, then write the code to pass more and more tests until all of them pass.) -1. VS Code displays tests results directly in the editor, where you can see that one test passed and one failed: +Because unit tests are small, isolated piece of code (in unit testing you avoid external dependencies and use mock data or otherwise simulated inputs), they're quick and inexpensive to run. This characteristic means means that you can run unit tests early and often. Developers typically run unit tests even before committing code to a repository; gated check-in systems can also run unit tests before merging a commit. Many continuous integration systems also run unit tests after every build. Running the unit test early and often means that you quickly catch *regressions,* which are unexpected changes in the behavior of code that previously passed all its unit tests. Because the test failure can easily be traced to a particular code change, it's easy to find and remedy the cause of the failure, which is undoubtedly better than discovering a problem much later in the process! - ![Test result adornments on a unit test method](images/unit-testing/result-adornments.png) +For a general background on unit testing, see [Unit Testing](https://wikipedia.org/wiki/Unit_testing) on Wikipedia. For a variety of useful unit test examples, see [https://github.com/gwtw/py-sorting](https://github.com/gwtw/py-sorting), a repository with tests for different sorting algorithms. - VS Code also shows test results in the **Python Test Log** output panel (use the **View** > **Output** menu command to show the **Output** panel, then select **Python Test Log** from the drop-down on the right side): +## Example test walkthroughs - ![Test results in the Python Test Log output panel](images/unit-testing/python-test-log-output.png) +Python tests are Python classes that reside in separate files from the code being tested. Each test framework specifies the structure and naming of tests and test files. Once you write tests and enable a test framework, VS Code locates those tests and provides you with various commands to run and debug them. -1. To more closely analyze a test, set a breakpoint on first the line in the `test_decrement` function, that reads `self.assertEqual(inc_dec.decrement(3), 4)`. Then select the **Debug Test** adornment above that function. VS Code starts the debugger and pauses at the breakpoint. In this case, you can use the **Debug Console** panel to enter `inc_dec.decrement(3)` and see the actual result is 2 and that the expected result of 4 is incorrect. Stop the debugger and correct that line of code: +For this section, create a folder and open it in VS Code. Then create a file named `inc_dec.py` with the following code to be tested: ```python - self.assertEqual(inc_dec.decrement(3), 2) - ``` + def increment(x): + return x + 1 -1. Save the file and run the test again to see that it passes. + def decrement(x): + return x - 1 + ``` -> **Note**: running or debugging a unit test does not automatically save the test file. Always be sure to save changes to a test before running it, otherwise you'll likely be confused by the results because they still reflect the previous version of the file! +With this code, you can experience working with tests in VS Code as described in the sections that follow. ## Enable a test framework @@ -93,7 +94,11 @@ Unit testing in Python is disabled by default. To enable unit testing, set *one It's important that you enable only a single test framework at a time. For this reason, when you enable one framework also be sure to disable the others. -To enable unittest, for example, use the following settings: +When you enable a test framework, VS Code prompts you to install the framework package if it's not already present in the currently activated environment: + +![VS Code prompt to install a test framework when enabled](images/unit-testing/install-framework.png) + +### Settings to enable unittest ```json "python.unitTest.unittestEnabled": true, @@ -101,7 +106,7 @@ To enable unittest, for example, use the following settings: "python.unitTest.nosetestsEnabled": false, ``` -To enable pyTest: +### Settings to enable pytest ```json "python.unitTest.unittestEnabled": false, @@ -109,7 +114,7 @@ To enable pyTest: "python.unitTest.nosetestsEnabled": false, ``` -To enable Nose: +### Settings to enable Nose ```json "python.unitTest.unittestEnabled": false, @@ -117,33 +122,91 @@ To enable Nose: "python.unitTest.nosetestsEnabled": true, ``` +## Create tests + +Each test framework has its own conventions for naming test files and structuring the tests within, as described in the following sections. Each case includes two test methods, one of which is intentionally set to fail for the purposes of demonstration. + +Because Nose is in maintenance mode and not recommended for new projects, only unittest and pytest examples are shown in the sections that follow. (Nose2, the successor to Nose, is just unittest with plugins, and so it follows the unittest patterns shown here.) + +### Tests in unittest + +Create a file named `test_unittest.py` that contains a test class with two test methods: + +```python +import inc_dec # The code to test +import unittest # The test framework + +class Test_TestIncrementDecrement(unittest.TestCase): + def test_increment(self): + self.assertEqual(inc_dec.increment(3), 4) + + def test_decrement(self): + self.assertEqual(inc_dec.decrement(3), 4) + +if __name__ == '__main__': + unittest.main() +``` + +### Tests in pytest + +Create a file named `test_pytest.py` that contains two test methods: + +```python +import inc_dec # The code to test + +def test_increment(): + assert inc_dec.increment(3) == 4 + +def test_decrement(): + assert inc_dec.decrement(3) == 4 +``` + ## Test discovery VS Code uses the currently enabled unit testing framework to discover tests. You can trigger test discovery at any time using the **Python: Discover Unit Tests** command. `python.unitTest.autoTestDiscoverOnSaveEnabled` is set to `true` by default, meaning test discovery is performed automatically whenever you save a test file. To disable this feature, set the value to `false`. -Test discovery applies the discovery patterns specified in the arguments setting for the current test framework: `python.unitTest.unittestArgs`, `python.unitTest.pyTestArgs`, or `python.unitTest.nosetestArgs` as described under [Test configuration settings](#test-configuration-settings). +Test discovery applies the discovery patterns for the current framework (which can be customized using the [Test configuration settings](#test-configuration-settings)). The default behavior is as follows: + +- `python.unitTest.unittestArgs`: Looks for any Python (`.py`) file with "test" in the name in the top-level project folder. All test files must be importable modules or packages. You can customize the file matching pattern with the `-p` configuration setting, and customize the folder with the `-t` setting. + +- `python.unitTest.pyTestArgs`: Looks for any Python (`.py`) file whose name begins with "test\_" or ends with "\_test", located anywhere within the current folder and all subfolders. > **Tip**: Sometimes unit tests placed in subfolders aren't discovered because such test files cannot be imported. To make them importable, create an empty file named `__init__.py` in that folder. +Once VS Code recognizes tests, it provides several ways to run those tests as described in [Run tests](#run-tests). The most obvious means are CodeLens adornments that appear directly in the editor and allow you to easily run a single test method or, with unittest, a test class: + +![Test adornments that appear in the VS Code editor for unittest code](images/unit-testing/editor-adornments-unittest.png) + +![Test adornments that appear in the VS Code editor for pytest code](images/unit-testing/editor-adornments-pytest.png) + + +> **Note**: At present, the Python extension doesn't provide a setting to turn the adornments on or off. To suggest a different behavior, file an issue on the [vscode-python repository](https://github.com/Microsoft/vscode-python/issues). + +If discovery fails (for example, the test framework isn't installed), you see a notification on the status bar. Selecting the notification provides more information: + +![Status bar showing that test discovery failed](images/unit-testing/discovery-failed-status-bar.png) + +If discovery succeeds, the status bar shows **Run Tests** instead: + +![Status bar showing successful test discovery failed](images/unit-testing/discovery-succeeded-status-bar.png) + ## Run tests You run tests using any of the following actions: -- Select `Run Tests` on the Status Bar (which can change appearance based on results), +- With a test file open, select the **Run Test** CodeLens adornment that appears above a test method or a class, as shown in the previous section. This command runs only that one method or only those tests in the class. - ![Test command on the VS Code status bar](images/unit-testing/status-bar-run-tests.png) +- Select **Run Tests** on the Status Bar (which can change appearance based on results), - then select one of the commands like `Run All Tests` or `Run Failed Unit Tests`: + ![Test command on the VS Code status bar](images/unit-testing/discovery-succeeded-status-bar.png) - ![Test commands that appear after using the Run Tests status bar command](images/unit-testing/run-test-commands.png) + then select one of the commands like **Run All Unit Tests** or **Run Failed Unit Tests**: -- Right-click a file in Explorer and select `Run Unit Tests`, which runs the tests in that one file. - -- Open a test file and select the `Run Test` CodeLens adornment that appears above a test class or a method. This command runs only those tests in the class or runs that one test method, respectively. + ![Test commands that appear after using the Run Tests status bar command](images/unit-testing/run-test-commands.png) - ![Python unit testing commands in the editor](images/unit-testing/editor-adornments.png) +- Right-click a file in Explorer and select **Run All Unit Tests**, which runs the tests in that one file. - From the **Command Palette**, select any of the run unit test commands: @@ -160,9 +223,45 @@ You run tests using any of the following actions: | Run Unit Test Method | Prompts for the name of a test to run, providing auto-completion for test names. | | Show Unit Test Output | Opens the Python Test Log panel with information about passing and failing tests, as well as errors and skipped tests. | +After a test run, VS Code displays results directly with the CodeLens adornments in the editor. Here, you can see that that one test passed and one failed. In the case of unittest, you can also see that the test class as a whole failed because at least one of its tests failed. In the case of pytest, failed tests are also adorned with a red underline. + +![Test result adornments on a unittest class](images/unit-testing/result-adornments-unittest.png) + +![Test result adornments on pytest methods](images/unit-testing/result-adornments-pytest.png) + +VS Code also shows test results in the **Python Test Log** output panel (use the **View** > **Output** menu command to show the **Output** panel, then select **Python Test Log** from the drop-down on the right side): + +![Test results in the Python Test Log output panel](images/unit-testing/python-test-log-output.png) + +With PyTest, failed tests also appear in the **Problems** panel, where you can double-click on an issue to navigate directly to the test: + +![Test results for pytest in the Problems panel](images/unit-testing/python-test-problems-output.png) + ## Debug tests -Because unit tests themselves are source code, they are prone to code defects just like the production code they test. For this reason, you may occasionally need to step through unit tests in the debugger. +Because unit tests themselves are source code, they are prone to code defects just like the production code they test. For this reason, you may occasionally need to step through and analyze unit tests in the debugger. + +For example, the `test_decrement` functions given earlier are failing because the assertion itself is faulty. The following steps demonstrate how to analyze the test: + +1. Set a breakpoint on first the line in the `test_decrement` function. + +1. Select the **Debug Test** adornment above that function. VS Code starts the debugger and pauses at the breakpoint. + +1. In the **Debug Console** panel, enter `inc_dec.decrement(3)` to see that the actual result is 2, whereas the expected result specified in the test is the incorrect value of 4. + +1. Stop the debugger and correct the faulty code: + + ```python + # unittest + self.assertEqual(inc_dec.decrement(3), 2) + + # pytest + assert inc_dec.decrement(3) == 4 + ``` + +1. Save the file and run the tests again to confirm that they pass, and see that the CodeLens adornments also indicate passing status. + + > **Note**: running or debugging a unit test does not automatically save the test file. Always be sure to save changes to a test before running it, otherwise you'll likely be confused by the results because they still reflect the previous version of the file! The **Python: Debug All Tests** and **Python: Debug Unit Test Method** commands (on both the Command Palette and Status Bar menu) launch the debugger for all tests and a single test method, respectively.