123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773 |
- <!DOCTYPE html><html><head><meta charset="utf-8"><style>body {
- width: 45em;
- border: 1px solid #ddd;
- outline: 1300px solid #fff;
- margin: 16px auto;
- }
-
- body .markdown-body
- {
- padding: 30px;
- }
-
- @font-face {
- font-family: octicons-anchor;
- src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAYcAA0AAAAACjQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABMAAAABwAAAAca8vGTk9TLzIAAAFMAAAARAAAAFZG1VHVY21hcAAAAZAAAAA+AAABQgAP9AdjdnQgAAAB0AAAAAQAAAAEACICiGdhc3AAAAHUAAAACAAAAAj//wADZ2x5ZgAAAdwAAADRAAABEKyikaNoZWFkAAACsAAAAC0AAAA2AtXoA2hoZWEAAALgAAAAHAAAACQHngNFaG10eAAAAvwAAAAQAAAAEAwAACJsb2NhAAADDAAAAAoAAAAKALIAVG1heHAAAAMYAAAAHwAAACABEAB2bmFtZQAAAzgAAALBAAAFu3I9x/Nwb3N0AAAF/AAAAB0AAAAvaoFvbwAAAAEAAAAAzBdyYwAAAADP2IQvAAAAAM/bz7t4nGNgZGFgnMDAysDB1Ml0hoGBoR9CM75mMGLkYGBgYmBlZsAKAtJcUxgcPsR8iGF2+O/AEMPsznAYKMwIkgMA5REMOXicY2BgYGaAYBkGRgYQsAHyGMF8FgYFIM0ChED+h5j//yEk/3KoSgZGNgYYk4GRCUgwMaACRoZhDwCs7QgGAAAAIgKIAAAAAf//AAJ4nHWMMQrCQBBF/0zWrCCIKUQsTDCL2EXMohYGSSmorScInsRGL2DOYJe0Ntp7BK+gJ1BxF1stZvjz/v8DRghQzEc4kIgKwiAppcA9LtzKLSkdNhKFY3HF4lK69ExKslx7Xa+vPRVS43G98vG1DnkDMIBUgFN0MDXflU8tbaZOUkXUH0+U27RoRpOIyCKjbMCVejwypzJJG4jIwb43rfl6wbwanocrJm9XFYfskuVC5K/TPyczNU7b84CXcbxks1Un6H6tLH9vf2LRnn8Ax7A5WQAAAHicY2BkYGAA4teL1+yI57f5ysDNwgAC529f0kOmWRiYVgEpDgYmEA8AUzEKsQAAAHicY2BkYGB2+O/AEMPCAAJAkpEBFbAAADgKAe0EAAAiAAAAAAQAAAAEAAAAAAAAKgAqACoAiAAAeJxjYGRgYGBhsGFgYgABEMkFhAwM/xn0QAIAD6YBhwB4nI1Ty07cMBS9QwKlQapQW3VXySvEqDCZGbGaHULiIQ1FKgjWMxknMfLEke2A+IJu+wntrt/QbVf9gG75jK577Lg8K1qQPCfnnnt8fX1NRC/pmjrk/zprC+8D7tBy9DHgBXoWfQ44Av8t4Bj4Z8CLtBL9CniJluPXASf0Lm4CXqFX8Q84dOLnMB17N4c7tBo1AS/Qi+hTwBH4rwHHwN8DXqQ30XXAS7QaLwSc0Gn8NuAVWou/gFmnjLrEaEh9GmDdDGgL3B4JsrRPDU2hTOiMSuJUIdKQQayiAth69r6akSSFqIJuA19TrzCIaY8sIoxyrNIrL//pw7A2iMygkX5vDj+G+kuoLdX4GlGK/8Lnlz6/h9MpmoO9rafrz7ILXEHHaAx95s9lsI7AHNMBWEZHULnfAXwG9/ZqdzLI08iuwRloXE8kfhXYAvE23+23DU3t626rbs8/8adv+9DWknsHp3E17oCf+Z48rvEQNZ78paYM38qfk3v/u3l3u3GXN2Dmvmvpf1Srwk3pB/VSsp512bA/GG5i2WJ7wu430yQ5K3nFGiOqgtmSB5pJVSizwaacmUZzZhXLlZTq8qGGFY2YcSkqbth6aW1tRmlaCFs2016m5qn36SbJrqosG4uMV4aP2PHBmB3tjtmgN2izkGQyLWprekbIntJFing32a5rKWCN/SdSoga45EJykyQ7asZvHQ8PTm6cslIpwyeyjbVltNikc2HTR7YKh9LBl9DADC0U/jLcBZDKrMhUBfQBvXRzLtFtjU9eNHKin0x5InTqb8lNpfKv1s1xHzTXRqgKzek/mb7nB8RZTCDhGEX3kK/8Q75AmUM/eLkfA+0Hi908Kx4eNsMgudg5GLdRD7a84npi+YxNr5i5KIbW5izXas7cHXIMAau1OueZhfj+cOcP3P8MNIWLyYOBuxL6DRylJ4cAAAB4nGNgYoAALjDJyIAOWMCiTIxMLDmZedkABtIBygAAAA==) format('woff');
- }
-
- .markdown-body {
- -ms-text-size-adjust: 100%;
- -webkit-text-size-adjust: 100%;
- color: #333;
- overflow: hidden;
- font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
- font-size: 16px;
- line-height: 1.6;
- word-wrap: break-word;
- }
-
- .markdown-body a {
- background: transparent;
- }
-
- .markdown-body a:active,
- .markdown-body a:hover {
- outline: 0;
- }
-
- .markdown-body strong {
- font-weight: bold;
- }
-
- .markdown-body h1 {
- font-size: 2em;
- margin: 0.67em 0;
- }
-
- .markdown-body img {
- border: 0;
- }
-
- .markdown-body hr {
- -moz-box-sizing: content-box;
- box-sizing: content-box;
- height: 0;
- }
-
- .markdown-body pre {
- overflow: auto;
- }
-
- .markdown-body code,
- .markdown-body kbd,
- .markdown-body pre {
- font-family: monospace, monospace;
- font-size: 1em;
- }
-
- .markdown-body input {
- color: inherit;
- font: inherit;
- margin: 0;
- }
-
- .markdown-body html input[disabled] {
- cursor: default;
- }
-
- .markdown-body input {
- line-height: normal;
- }
-
- .markdown-body input[type="checkbox"] {
- -moz-box-sizing: border-box;
- box-sizing: border-box;
- padding: 0;
- }
-
- .markdown-body table {
- border-collapse: collapse;
- border-spacing: 0;
- }
-
- .markdown-body td,
- .markdown-body th {
- padding: 0;
- }
-
- .markdown-body * {
- -moz-box-sizing: border-box;
- box-sizing: border-box;
- }
-
- .markdown-body input {
- font: 13px/1.4 Helvetica, arial, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol";
- }
-
- .markdown-body a {
- color: #4183c4;
- text-decoration: none;
- }
-
- .markdown-body a:hover,
- .markdown-body a:focus,
- .markdown-body a:active {
- text-decoration: underline;
- }
-
- .markdown-body hr {
- height: 0;
- margin: 15px 0;
- overflow: hidden;
- background: transparent;
- border: 0;
- border-bottom: 1px solid #ddd;
- }
-
- .markdown-body hr:before {
- display: table;
- content: "";
- }
-
- .markdown-body hr:after {
- display: table;
- clear: both;
- content: "";
- }
-
- .markdown-body h1,
- .markdown-body h2,
- .markdown-body h3,
- .markdown-body h4,
- .markdown-body h5,
- .markdown-body h6 {
- margin-top: 15px;
- margin-bottom: 15px;
- line-height: 1.1;
- }
-
- .markdown-body h1 {
- font-size: 30px;
- }
-
- .markdown-body h2 {
- font-size: 21px;
- }
-
- .markdown-body h3 {
- font-size: 16px;
- }
-
- .markdown-body h4 {
- font-size: 14px;
- }
-
- .markdown-body h5 {
- font-size: 12px;
- }
-
- .markdown-body h6 {
- font-size: 11px;
- }
-
- .markdown-body blockquote {
- margin: 0;
- }
-
- .markdown-body ul,
- .markdown-body ol {
- padding: 0;
- margin-top: 0;
- margin-bottom: 0;
- }
-
- .markdown-body ol ol,
- .markdown-body ul ol {
- list-style-type: lower-roman;
- }
-
- .markdown-body ul ul ol,
- .markdown-body ul ol ol,
- .markdown-body ol ul ol,
- .markdown-body ol ol ol {
- list-style-type: lower-alpha;
- }
-
- .markdown-body dd {
- margin-left: 0;
- }
-
- .markdown-body code {
- font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace;
- }
-
- .markdown-body pre {
- margin-top: 0;
- margin-bottom: 0;
- font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace;
- }
-
- .markdown-body .octicon {
- font: normal normal 16px octicons-anchor;
- line-height: 1;
- display: inline-block;
- text-decoration: none;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- }
-
- .markdown-body .octicon-link:before {
- content: '\f05c';
- }
-
- .markdown-body>*:first-child {
- margin-top: 0 !important;
- }
-
- .markdown-body>*:last-child {
- margin-bottom: 0 !important;
- }
-
- .markdown-body .anchor {
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- display: block;
- padding-right: 6px;
- padding-left: 30px;
- margin-left: -30px;
- }
-
- .markdown-body .anchor:focus {
- outline: none;
- }
-
- .markdown-body h1,
- .markdown-body h2,
- .markdown-body h3,
- .markdown-body h4,
- .markdown-body h5,
- .markdown-body h6 {
- position: relative;
- margin-top: 1em;
- margin-bottom: 16px;
- font-weight: bold;
- line-height: 1.4;
- }
-
- .markdown-body h1 .octicon-link,
- .markdown-body h2 .octicon-link,
- .markdown-body h3 .octicon-link,
- .markdown-body h4 .octicon-link,
- .markdown-body h5 .octicon-link,
- .markdown-body h6 .octicon-link {
- display: none;
- color: #000;
- vertical-align: middle;
- }
-
- .markdown-body h1:hover .anchor,
- .markdown-body h2:hover .anchor,
- .markdown-body h3:hover .anchor,
- .markdown-body h4:hover .anchor,
- .markdown-body h5:hover .anchor,
- .markdown-body h6:hover .anchor {
- padding-left: 8px;
- margin-left: -30px;
- line-height: 1;
- text-decoration: none;
- }
-
- .markdown-body h1:hover .anchor .octicon-link,
- .markdown-body h2:hover .anchor .octicon-link,
- .markdown-body h3:hover .anchor .octicon-link,
- .markdown-body h4:hover .anchor .octicon-link,
- .markdown-body h5:hover .anchor .octicon-link,
- .markdown-body h6:hover .anchor .octicon-link {
- display: inline-block;
- }
-
- .markdown-body h1 {
- padding-bottom: 0.3em;
- font-size: 2.25em;
- line-height: 1.2;
- border-bottom: 1px solid #eee;
- }
-
- .markdown-body h2 {
- padding-bottom: 0.3em;
- font-size: 1.75em;
- line-height: 1.225;
- border-bottom: 1px solid #eee;
- }
-
- .markdown-body h3 {
- font-size: 1.5em;
- line-height: 1.43;
- }
-
- .markdown-body h4 {
- font-size: 1.25em;
- }
-
- .markdown-body h5 {
- font-size: 1em;
- }
-
- .markdown-body h6 {
- font-size: 1em;
- color: #777;
- }
-
- .markdown-body p,
- .markdown-body blockquote,
- .markdown-body ul,
- .markdown-body ol,
- .markdown-body dl,
- .markdown-body table,
- .markdown-body pre {
- margin-top: 0;
- margin-bottom: 16px;
- }
-
- .markdown-body hr {
- height: 4px;
- padding: 0;
- margin: 16px 0;
- background-color: #e7e7e7;
- border: 0 none;
- }
-
- .markdown-body ul,
- .markdown-body ol {
- padding-left: 2em;
- }
-
- .markdown-body ul ul,
- .markdown-body ul ol,
- .markdown-body ol ol,
- .markdown-body ol ul {
- margin-top: 0;
- margin-bottom: 0;
- }
-
- .markdown-body li>p {
- margin-top: 16px;
- }
-
- .markdown-body dl {
- padding: 0;
- }
-
- .markdown-body dl dt {
- padding: 0;
- margin-top: 16px;
- font-size: 1em;
- font-style: italic;
- font-weight: bold;
- }
-
- .markdown-body dl dd {
- padding: 0 16px;
- margin-bottom: 16px;
- }
-
- .markdown-body blockquote {
- padding: 0 15px;
- color: #777;
- border-left: 4px solid #ddd;
- }
-
- .markdown-body blockquote>:first-child {
- margin-top: 0;
- }
-
- .markdown-body blockquote>:last-child {
- margin-bottom: 0;
- }
-
- .markdown-body table {
- display: block;
- width: 100%;
- overflow: auto;
- word-break: normal;
- word-break: keep-all;
- }
-
- .markdown-body table th {
- font-weight: bold;
- }
-
- .markdown-body table th,
- .markdown-body table td {
- padding: 6px 13px;
- border: 1px solid #ddd;
- }
-
- .markdown-body table tr {
- background-color: #fff;
- border-top: 1px solid #ccc;
- }
-
- .markdown-body table tr:nth-child(2n) {
- background-color: #f8f8f8;
- }
-
- .markdown-body img {
- max-width: 100%;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
- }
-
- .markdown-body code {
- padding: 0;
- padding-top: 0.2em;
- padding-bottom: 0.2em;
- margin: 0;
- font-size: 85%;
- background-color: rgba(0,0,0,0.04);
- border-radius: 3px;
- }
-
- .markdown-body code:before,
- .markdown-body code:after {
- letter-spacing: -0.2em;
- content: "\00a0";
- }
-
- .markdown-body pre>code {
- padding: 0;
- margin: 0;
- font-size: 100%;
- word-break: normal;
- white-space: pre;
- background: transparent;
- border: 0;
- }
-
- .markdown-body .highlight {
- margin-bottom: 16px;
- }
-
- .markdown-body .highlight pre,
- .markdown-body pre {
- padding: 16px;
- overflow: auto;
- font-size: 85%;
- line-height: 1.45;
- background-color: #f7f7f7;
- border-radius: 3px;
- }
-
- .markdown-body .highlight pre {
- margin-bottom: 0;
- word-break: normal;
- }
-
- .markdown-body pre {
- word-wrap: normal;
- }
-
- .markdown-body pre code {
- display: inline;
- max-width: initial;
- padding: 0;
- margin: 0;
- overflow: initial;
- line-height: inherit;
- word-wrap: normal;
- background-color: transparent;
- border: 0;
- }
-
- .markdown-body pre code:before,
- .markdown-body pre code:after {
- content: normal;
- }
-
- .markdown-body .highlight {
- background: #fff;
- }
-
- .markdown-body .highlight .h {
- color: #333;
- font-style: normal;
- font-weight: normal;
- }
-
- .markdown-body .highlight .mf,
- .markdown-body .highlight .mh,
- .markdown-body .highlight .mi,
- .markdown-body .highlight .mo,
- .markdown-body .highlight .il,
- .markdown-body .highlight .m {
- color: #945277;
- }
-
- .markdown-body .highlight .s,
- .markdown-body .highlight .sb,
- .markdown-body .highlight .sc,
- .markdown-body .highlight .sd,
- .markdown-body .highlight .s2,
- .markdown-body .highlight .se,
- .markdown-body .highlight .sh,
- .markdown-body .highlight .si,
- .markdown-body .highlight .sx,
- .markdown-body .highlight .s1 {
- color: #df5000;
- }
-
- .markdown-body .highlight .kc,
- .markdown-body .highlight .kd,
- .markdown-body .highlight .kn,
- .markdown-body .highlight .kp,
- .markdown-body .highlight .kr,
- .markdown-body .highlight .kt,
- .markdown-body .highlight .k,
- .markdown-body .highlight .o {
- font-weight: bold;
- }
-
- .markdown-body .highlight .kt {
- color: #458;
- }
-
- .markdown-body .highlight .c,
- .markdown-body .highlight .cm,
- .markdown-body .highlight .c1 {
- color: #998;
- font-style: italic;
- }
-
- .markdown-body .highlight .cp,
- .markdown-body .highlight .cs,
- .markdown-body .highlight .cp .h {
- color: #999;
- font-weight: bold;
- }
-
- .markdown-body .highlight .cs {
- font-style: italic;
- }
-
- .markdown-body .highlight .n {
- color: #333;
- }
-
- .markdown-body .highlight .na,
- .markdown-body .highlight .nv,
- .markdown-body .highlight .vc,
- .markdown-body .highlight .vg,
- .markdown-body .highlight .vi {
- color: #008080;
- }
-
- .markdown-body .highlight .nb {
- color: #0086B3;
- }
-
- .markdown-body .highlight .nc {
- color: #458;
- font-weight: bold;
- }
-
- .markdown-body .highlight .no {
- color: #094e99;
- }
-
- .markdown-body .highlight .ni {
- color: #800080;
- }
-
- .markdown-body .highlight .ne {
- color: #990000;
- font-weight: bold;
- }
-
- .markdown-body .highlight .nf {
- color: #945277;
- font-weight: bold;
- }
-
- .markdown-body .highlight .nn {
- color: #555;
- }
-
- .markdown-body .highlight .nt {
- color: #000080;
- }
-
- .markdown-body .highlight .err {
- color: #a61717;
- background-color: #e3d2d2;
- }
-
- .markdown-body .highlight .gd {
- color: #000;
- background-color: #fdd;
- }
-
- .markdown-body .highlight .gd .x {
- color: #000;
- background-color: #faa;
- }
-
- .markdown-body .highlight .ge {
- font-style: italic;
- }
-
- .markdown-body .highlight .gr {
- color: #aa0000;
- }
-
- .markdown-body .highlight .gh {
- color: #999;
- }
-
- .markdown-body .highlight .gi {
- color: #000;
- background-color: #dfd;
- }
-
- .markdown-body .highlight .gi .x {
- color: #000;
- background-color: #afa;
- }
-
- .markdown-body .highlight .go {
- color: #888;
- }
-
- .markdown-body .highlight .gp {
- color: #555;
- }
-
- .markdown-body .highlight .gs {
- font-weight: bold;
- }
-
- .markdown-body .highlight .gu {
- color: #800080;
- font-weight: bold;
- }
-
- .markdown-body .highlight .gt {
- color: #aa0000;
- }
-
- .markdown-body .highlight .ow {
- font-weight: bold;
- }
-
- .markdown-body .highlight .w {
- color: #bbb;
- }
-
- .markdown-body .highlight .sr {
- color: #017936;
- }
-
- .markdown-body .highlight .ss {
- color: #8b467f;
- }
-
- .markdown-body .highlight .bp {
- color: #999;
- }
-
- .markdown-body .highlight .gc {
- color: #999;
- background-color: #EAF2F5;
- }
-
- .markdown-body kbd {
- background-color: #e7e7e7;
- background-image: -webkit-linear-gradient(#fefefe, #e7e7e7);
- background-image: linear-gradient(#fefefe, #e7e7e7);
- background-repeat: repeat-x;
- display: inline-block;
- padding: 3px 5px;
- font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace;
- line-height: 10px;
- color: #000;
- border: 1px solid #cfcfcf;
- border-radius: 2px;
- }
-
- .markdown-body .highlight .pl-coc,
- .markdown-body .highlight .pl-entm,
- .markdown-body .highlight .pl-eoa,
- .markdown-body .highlight .pl-mai .pl-sf,
- .markdown-body .highlight .pl-pdv,
- .markdown-body .highlight .pl-sc,
- .markdown-body .highlight .pl-sr,
- .markdown-body .highlight .pl-v,
- .markdown-body .highlight .pl-vpf {
- color: #0086b3;
- }
-
- .markdown-body .highlight .pl-eoac,
- .markdown-body .highlight .pl-mdht,
- .markdown-body .highlight .pl-mi1,
- .markdown-body .highlight .pl-mri,
- .markdown-body .highlight .pl-va,
- .markdown-body .highlight .pl-vpu {
- color: #008080;
- }
-
- .markdown-body .highlight .pl-c,
- .markdown-body .highlight .pl-pdc {
- color: #b4b7b4;
- font-style: italic;
- }
-
- .markdown-body .highlight .pl-k,
- .markdown-body .highlight .pl-ko,
- .markdown-body .highlight .pl-kolp,
- .markdown-body .highlight .pl-mc,
- .markdown-body .highlight .pl-mr,
- .markdown-body .highlight .pl-ms,
- .markdown-body .highlight .pl-s,
- .markdown-body .highlight .pl-sok,
- .markdown-body .highlight .pl-st {
- color: #6e5494;
- }
-
- .markdown-body .highlight .pl-ef,
- .markdown-body .highlight .pl-enf,
- .markdown-body .highlight .pl-enm,
- .markdown-body .highlight .pl-entc,
- .markdown-body .highlight .pl-eoi,
- .markdown-body .highlight .pl-sf,
- .markdown-body .highlight .pl-smc {
- color: #d12089;
- }
-
- .markdown-body .highlight .pl-ens,
- .markdown-body .highlight .pl-eoai,
- .markdown-body .highlight .pl-kos,
- .markdown-body .highlight .pl-mh .pl-pdh,
- .markdown-body .highlight .pl-mp,
- .markdown-body .highlight .pl-pde,
- .markdown-body .highlight .pl-stp {
- color: #458;
- }
-
- .markdown-body .highlight .pl-enti {
- color: #d12089;
- font-weight: bold;
- }
-
- .markdown-body .highlight .pl-cce,
- .markdown-body .highlight .pl-enc,
- .markdown-body .highlight .pl-kou,
- .markdown-body .highlight .pl-mq {
- color: #f93;
- }
-
- .markdown-body .highlight .pl-mp1 .pl-sf {
- color: #458;
- font-weight: bold;
- }
-
- .markdown-body .highlight .pl-cos,
- .markdown-body .highlight .pl-ent,
- .markdown-body .highlight .pl-md,
- .markdown-body .highlight .pl-mdhf,
- .markdown-body .highlight .pl-ml,
- .markdown-body .highlight .pl-pdc1,
- .markdown-body .highlight .pl-pds,
- .markdown-body .highlight .pl-s1,
- .markdown-body .highlight .pl-scp,
- .markdown-body .highlight .pl-sol {
- color: #df5000;
- }
-
- .markdown-body .highlight .pl-c1,
- .markdown-body .highlight .pl-cn,
- .markdown-body .highlight .pl-pse,
- .markdown-body .highlight .pl-pse .pl-s2,
- .markdown-body .highlight .pl-vi {
- color: #a31515;
- }
-
- .markdown-body .highlight .pl-mb,
- .markdown-body .highlight .pl-pdb {
- color: #df5000;
- font-weight: bold;
- }
-
- .markdown-body .highlight .pl-mi,
- .markdown-body .highlight .pl-pdi {
- color: #6e5494;
- font-style: italic;
- }
-
- .markdown-body .highlight .pl-ms1 {
- background-color: #f5f5f5;
- }
-
- .markdown-body .highlight .pl-mdh,
- .markdown-body .highlight .pl-mdi {
- font-weight: bold;
- }
-
- .markdown-body .highlight .pl-mdr {
- color: #0086b3;
- font-weight: bold;
- }
-
- .markdown-body .highlight .pl-s2 {
- color: #333;
- }
-
- .markdown-body .highlight .pl-ii {
- background-color: #df5000;
- color: #fff;
- }
-
- .markdown-body .highlight .pl-ib {
- background-color: #f93;
- }
-
- .markdown-body .highlight .pl-id {
- background-color: #a31515;
- color: #fff;
- }
-
- .markdown-body .highlight .pl-iu {
- background-color: #b4b7b4;
- }
-
- .markdown-body .highlight .pl-mo {
- color: #969896;
- }
-
- .markdown-body .task-list-item {
- list-style-type: none;
- }
-
- .markdown-body .task-list-item+.task-list-item {
- margin-top: 3px;
- }
-
- .markdown-body .task-list-item input {
- float: left;
- margin: 0.3em 0 0.25em -1.6em;
- vertical-align: middle;
- }</style><script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
- <script>
- MathJax.Hub.Config({
- config: ["MMLorHTML.js"],
- extensions: ["tex2jax.js"],
- jax: ["input/TeX"],
- tex2jax: {
- inlineMath: [ ['$','$'], ["\\(","\\)"] ],
- displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
- processEscapes: false
- },
- TeX: {
- extensions: ["AMSmath.js", "AMSsymbols.js"],
- TagSide: "right",
- TagIndent: ".8em",
- MultLineWidth: "85%",
- equationNumbers: {
- autoNumber: "AMS",
- },
- unicode: {
- fonts: "STIXGeneral,'Arial Unicode MS'"
- }
- },
- showProcessingMessages: false
- });
- </script>
- <title>Testing</title></head><body><article class="markdown-body"><p><a href="#markdown-header-testing-and-unit-testing">English</a> | <a href="#markdown-header-pruebas-y-pruebas-unitarias">Español</a></p>
-
- <h1>
- <a id="user-content-pruebas-y-pruebas-unitarias" class="anchor" href="#pruebas-y-pruebas-unitarias" aria-hidden="true"><span class="octicon octicon-link"></span></a>Pruebas y pruebas unitarias</h1>
-
- <p><a href="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/main1.png" target="_blank"><img src="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/main1.png" alt="main1.png" style="max-width:100%;"></a>
- <a href="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/main2.png" target="_blank"><img src="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/main2.png" alt="main2.png" style="max-width:100%;"></a>
- <a href="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/main3.png" target="_blank"><img src="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/main3.png" alt="main3.png" style="max-width:100%;"></a></p>
-
- <p>Como habrás aprendido en experiencias de laboratorio anteriores, lograr que un programa compile es solo una pequeña parte de programar. El compilador se encargará de decirte si hubo errores de sintaxis, pero no podrá detectar errores en la lógica del programa. Es muy importante el probar las funciones del programa para validar que producen los resultados correctos y esperados.</p>
-
- <p>Una manera de hacer estas pruebas es “a mano”, esto es, corriendo el programa múltiples veces, ingresando valores representativos (por medio del teclado) y visualmente verificando que el programa devuelve los valores esperados. Una forma más conveniente es implementar funciones dentro del programa cuyo propósito es verificar que otras funciones produzcan resultados correctos. En esta experiencia de laboratorio practicarás ambos métodos de verificación.</p>
-
- <h2>
- <a id="user-content-objetivos" class="anchor" href="#objetivos" aria-hidden="true"><span class="octicon octicon-link"></span></a>Objetivos:</h2>
-
- <ol>
- <li>Validar el funcionamiento de varias funciones haciendo pruebas "a mano".</li>
- <li>Crear pruebas unitarias para validar funciones, utilizando la función <code>assert</code> </li>
- </ol>
-
- <h2>
- <a id="user-content-pre-lab" class="anchor" href="#pre-lab" aria-hidden="true"><span class="octicon octicon-link"></span></a>Pre-Lab:</h2>
-
- <p>Antes de llegar al laboratorio debes:</p>
-
- <ol>
- <li><p>Haber repasado los conceptos básicos relacionados a pruebas y pruebas unitarias.</p></li>
- <li><p>Haber repasado el uso de la función <code>assert</code> para hacer pruebas.</p></li>
- <li><p>Haber estudiado los conceptos e instrucciones para la sesión de laboratorio.</p></li>
- <li><p>Haber tomado el quiz Pre-Lab que se encuentra en Moodle.</p></li>
- </ol>
-
- <hr>
-
- <hr>
-
- <h2>
- <a id="user-content-haciendo-pruebas-a-una-función" class="anchor" href="#haciendo-pruebas-a-una-funci%C3%B3n" aria-hidden="true"><span class="octicon octicon-link"></span></a>Haciendo pruebas a una función.</h2>
-
- <p>Cuando probamos la validez de una función debemos probar casos que activen los diversos resultados de la función. </p>
-
- <hr>
-
- <p><strong>Ejemplo 1:</strong> si fueras a validar una función <code>esPar(unsigned int n)</code> que determina si un entero positivo <em>n</em> es par, deberías hacer pruebas a la función tanto con números pares como números impares. Un conjunto adecuado de pruebas para dicha función podría ser:</p>
-
- <table>
- <thead>
- <tr>
- <th>Prueba</th>
- <th>Resultado esperado</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><code>esPar(8)</code></td>
- <td>true</td>
- </tr>
- <tr>
- <td><code>esPar(7)</code></td>
- <td>false</td>
- </tr>
- </tbody>
- </table>
-
- <hr>
-
- <p><strong>Ejemplo 2:</strong> Digamos que un amigo ha creado una función <code>unsigned int rangoEdad(unsigned int edad)</code> que se supone que devuelva 0 si la edad está entre 0 y 5 (inclusive), 1 si la edad está entre 6 y 18 inclusive, y 2 si la edad es mayor de 18. Una fuente común de errores en funciones como esta son los valores próximos a los límites de cada rango, por ejemplo, el número 5 se presta para error si el programador no usó una comparación correcta. Un conjunto adecuado de pruebas para la función <code>rangoEdad</code> sería:</p>
-
- <table>
- <thead>
- <tr>
- <th>Prueba</th>
- <th>Resultado esperado</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><code>rangoEdad(5)</code></td>
- <td>0</td>
- </tr>
- <tr>
- <td><code>rangoEdad(2)</code></td>
- <td>0</td>
- </tr>
- <tr>
- <td><code>rangoEdad(6)</code></td>
- <td>1</td>
- </tr>
- <tr>
- <td><code>rangoEdad(18)</code></td>
- <td>1</td>
- </tr>
- <tr>
- <td><code>rangoEdad(17)</code></td>
- <td>1</td>
- </tr>
- <tr>
- <td><code>rangoEdad(19)</code></td>
- <td>2</td>
- </tr>
- <tr>
- <td><code>rangoEdad(25)</code></td>
- <td>2</td>
- </tr>
- </tbody>
- </table>
-
- <hr>
-
- <h3>
- <a id="user-content-la-función-assert" class="anchor" href="#la-funci%C3%B3n-assert" aria-hidden="true"><span class="octicon octicon-link"></span></a>La función <code>assert</code>
- </h3>
-
- <p>La función <code>assert(bool expression)</code> se puede utilizar como herramienta rudimentaria para validar de funciones. <code>assert</code> tiene un funcionamiento muy sencillo y poderoso. Si la expresión que colocamos entre los paréntesis de <code>assert</code> es <em>cierta</em> la función permite que el programa continúe con la próxima instrucción. De lo contrario, si la expresión que colocamos entre los paréntesis es <em>falsa</em>, la función <code>assert</code> hace que el programa termine e imprime un mensaje al terminal que informa al usuario sobre la instrucción de <code>assert</code> que falló. </p>
-
- <p>Por ejemplo, el siguiente programa correrá de principio a fin sin problemas pues todos las expresiones incluidas en los paréntesis de los asserts evalúan a <em>true</em>.</p>
-
- <hr>
-
- <div class="highlight highlight-cpp"><pre>#<span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds"><</span>iostream<span class="pl-pds">></span></span>
- #<span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds"><</span>cassert<span class="pl-pds">></span></span>
- <span class="pl-k">using</span> <span class="pl-k">namespace</span> <span class="pl-en">std</span><span class="pl-k">;</span>
-
- <span class="pl-k">int</span> <span class="pl-en">main</span>() {
- <span class="pl-k">int</span> i = <span class="pl-c1">10</span>, j = <span class="pl-c1">15</span>;
- <span class="pl-c1">assert</span>(i == <span class="pl-c1">10</span>);
- <span class="pl-c1">assert</span>(j == i + <span class="pl-c1">5</span>);
- <span class="pl-c1">assert</span>(j != i);
- <span class="pl-c1">assert</span>( (j < i) == <span class="pl-c1">false</span>);
- cout << <span class="pl-s"><span class="pl-pds">"</span>Eso es todo, amigos!<span class="pl-pds">"</span></span> << endl;
- <span class="pl-k">return</span> <span class="pl-c1">0</span>;
- }
- </pre></div>
-
- <p><strong>Figura 1.</strong> Ejemplo de programa que pasa todas las pruebas de <code>assert</code>.</p>
-
- <hr>
-
- <p>El siguiente programa no correrá hasta el final pues el segundo <code>assert</code> (<code>assert(j == i);</code>) contiene una expresión (<code>j==i</code>) que evalúa a <em>false</em>.</p>
-
- <hr>
-
- <div class="highlight highlight-cpp"><pre>
- #<span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds"><</span>iostream<span class="pl-pds">></span></span>
- #<span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds"><</span>cassert<span class="pl-pds">></span></span>
- <span class="pl-k">using</span> <span class="pl-k">namespace</span> <span class="pl-en">std</span><span class="pl-k">;</span>
-
- <span class="pl-k">int</span> <span class="pl-en">main</span>() {
- <span class="pl-k">int</span> i = <span class="pl-c1">10</span>, j = <span class="pl-c1">15</span>;
- <span class="pl-c1">assert</span>(i == <span class="pl-c1">10</span>);
- <span class="pl-c1">assert</span>(j == i);
- <span class="pl-c1">assert</span>(j != i);
- <span class="pl-c1">assert</span>( (j < i) == <span class="pl-c1">false</span>);
- cout << <span class="pl-s"><span class="pl-pds">"</span>Eso es todo, amigos!<span class="pl-pds">"</span></span> << endl;
- <span class="pl-k">return</span> <span class="pl-c1">0</span>;
- }
- </pre></div>
-
- <p><strong>Figura 2.</strong> Ejemplo de programa que no "pasa" una prueba de <code>assert</code>.</p>
-
- <hr>
-
- <p>Al correr el pasado programa, en lugar de obtener la frase <code>”Eso es todo amigos!”</code> en el terminal, obtendremos un mensaje como el siguiente:</p>
-
- <p><code>Assertion failed: (j == i), function main, file ../programa01/main.cpp, line 8.</code></p>
-
- <p>El programa no ejecuta más instrucciones después de la línea 8.</p>
-
- <h4>
- <a id="user-content-cómo-usar-assert-para-validar-funciones" class="anchor" href="#c%C3%B3mo-usar-assert-para-validar-funciones" aria-hidden="true"><span class="octicon octicon-link"></span></a>¿Cómo usar assert para validar funciones?</h4>
-
- <p>Digamos que deseas automatizar la validación de la función <code>rangoEdad</code>. Un forma de hacerlo es crear una función que llame a la función <code>rangoEdad</code> con diversos argumentos y verifique que lo devuelto concuerde con el resultado esperado. Si incluimos cada comparación entre lo devuelto por <code>rangoEdad</code> y el resultado esperado dentro de un <code>assert</code>, obtenemos una función que se ejecuta de principio a fin solo si todas las invocaciones devolvieron el resultado esperado.</p>
-
- <hr>
-
- <div class="highlight highlight-cpp"><pre><span class="pl-k">void</span> <span class="pl-en">test_rangoEdad</span>() {
- <span class="pl-c1">assert</span>(<span class="pl-c1">rangoEdad</span>(<span class="pl-c1">5</span>) == <span class="pl-c1">0</span>);
- <span class="pl-c1">assert</span>(<span class="pl-c1">rangoEdad</span>(<span class="pl-c1">2</span>) == <span class="pl-c1">0</span>);
- <span class="pl-c1">assert</span>(<span class="pl-c1">rangoEdad</span>(<span class="pl-c1">6</span>) == <span class="pl-c1">1</span>);
- <span class="pl-c1">assert</span>(<span class="pl-c1">rangoEdad</span>(<span class="pl-c1">18</span>) == <span class="pl-c1">1</span>);
- <span class="pl-c1">assert</span>(<span class="pl-c1">rangoEdad</span>(<span class="pl-c1">17</span>) == <span class="pl-c1">1</span>);
- <span class="pl-c1">assert</span>(<span class="pl-c1">rangoEdad</span>(<span class="pl-c1">19</span>) == <span class="pl-c1">2</span>);
- <span class="pl-c1">assert</span>(<span class="pl-c1">rangoEdad</span>(<span class="pl-c1">25</span>) == <span class="pl-c1">2</span>);
- cout << <span class="pl-s"><span class="pl-pds">"</span>rangoEdad passed all tests!!!<span class="pl-pds">"</span></span> << endl;
- }</pre></div>
-
- <p><strong>Figura 3.</strong> Ejemplo de una función para pruebas usando <code>assert</code>.</p>
-
- <hr>
-
- <hr>
-
- <h2>
- <a id="user-content-sesión-de-laboratorio" class="anchor" href="#sesi%C3%B3n-de-laboratorio" aria-hidden="true"><span class="octicon octicon-link"></span></a>Sesión de laboratorio:</h2>
-
- <h3>
- <a id="user-content-ejercicio-1-diseñar-pruebas-a-mano" class="anchor" href="#ejercicio-1-dise%C3%B1ar-pruebas-a-mano" aria-hidden="true"><span class="octicon octicon-link"></span></a>Ejercicio 1: Diseñar pruebas "a mano"</h3>
-
- <p>En este ejercicio practicarás cómo diseñar pruebas para validar funciones, utilizando solamente la descripción de la función y la interfaz que se usa para interactuar con la función. </p>
-
- <p>El ejercicio <strong>NO requiere programación</strong>, solo requiere que entiendas la descripción de la función, y tu habilidad para diseñar pruebas. Este ejercicio y el Ejercicio 2 son una adaptación del ejercicio en [1].</p>
-
- <p><strong>Ejemplo 3.</strong> Supón que una amiga te provee un programa. Ella asegura que el programa resuelve el siguiente problema: </p>
-
- <p><code>"dados tres enteros, despliega el valor máximo".</code> </p>
-
- <p>Supón que el programa tienen una interfaz como la siguiente:</p>
-
- <hr>
-
- <p><a href="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure4.png" target="_blank"><img src="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure4.png" alt="figure4.png" style="max-width:100%;"></a></p>
-
- <p><strong>Figura 4</strong> - Interfaz de un programa para hallar el valor máximo entre tres enteros.</p>
-
- <hr>
-
- <p>Podrías determinar si el programa provee resultados válidos <strong>sin analizar el código fuente</strong>. Por ejemplo, podrías intentar los siguientes casos:</p>
-
- <ul>
- <li>a = 4, b = 2, c = 1; resultado esperado: 4</li>
- <li>a = 3, b = 6, c = 2; resultado esperado: 6</li>
- <li>a = 1, b = 10, c = 100; resultado esperado: 100</li>
- </ul>
-
- <p>Si alguno de estos tres casos no da el resultado esperado, el programa de tu amiga no funciona. Por otro lado, si los tres casos funcionan, entonces el programa tiene una probabilidad alta de estar correcto.</p>
-
- <h4>
- <a id="user-content-funciones-para-validar" class="anchor" href="#funciones-para-validar" aria-hidden="true"><span class="octicon octicon-link"></span></a>Funciones para validar</h4>
-
- <p>En este ejercicio estarás diseñando pruebas que validen varias versiones de las funciones que se describen abajo. Cada una de las funciones tiene cuatro versiones, "Alpha", "Beta", "Gamma" y "Delta".</p>
-
- <ul>
- <li>
- <p><strong>3 Sorts:</strong> una función que recibe tres "strings" y los ordena en orden lexicográfico (alfabético). Por ejemplo, dados <code>jirafa</code>, <code>zorra</code>, y <code>coqui</code>, los ordena como: <code>coqui</code>, <code>jirafa</code>, y <code>zorra</code>. Para simplificar el ejercicio, solo usaremos "strings" con letras minúsculas. La Figura 5 muestra la interfaz de esta función. Nota que hay un menú para seleccionar la versión implementada.</p>
-
- <hr>
-
- <p><a href="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure5.png" target="_blank"><img src="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure5.png" alt="figure5.png" style="max-width:100%;"></a></p>
-
- <p><strong>Figura 5</strong> - Interfaz de la función <code>3 Sorts</code>.</p>
-
- <hr>
- </li>
- <li>
- <p><strong>Dice:</strong> cuando el usuario marca el botón <code>Roll them!</code>, el programa genera dos números aleatorios entre 1 y 6. El programa informa la suma de los números aleatorios. </p>
-
- <hr>
-
- <p><a href="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure6.png" target="_blank"><img src="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure6.png" alt="figure6.png" style="max-width:100%;"></a></p>
-
- <p><strong>Figura 6</strong> - Interfaz de la función <code>Dice</code>.</p>
-
- <hr>
- </li>
- <li>
- <p><strong>Rock, Paper, Scissors:</strong> cada uno de los jugadores entra su jugada y el programa informa quién ganó. La Figura 7 muestra las opciones en las que un objeto le gana a otro. La interfaz del juego se muestra en la Figura 8.</p>
-
- <hr>
-
- <p><a href="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure7.jpg" target="_blank"><img src="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure7.jpg" alt="figure7.jpg" style="max-width:100%;"></a></p>
-
- <p><strong>Figura 7</strong> - Formas de ganar en el juego "Piedra, papel y tijera".</p>
-
- <hr>
-
- <p><a href="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure8.png" target="_blank"><img src="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure8.png" alt="figure8.png" style="max-width:100%;"></a></p>
-
- <p><strong>Figura 8</strong> - Interfaz de la función <code>Rock, Paper, Scissors</code>.</p>
-
- <hr>
- </li>
- <li>
- <p><strong>Zulu time:</strong> Dada una hora en tiempo Zulu (Hora en el Meridiano de Greenwich) y la zona militar en la que el usuario desea saber la hora, el programa muestra la hora en esa zona. El formato para el dato de entrada es en formato de 23 horas <code>####</code>, por ejemplo <code>2212</code> sería las 10:12 pm. La lista de zonas militares válidas la puedes encontrar en <a href="http://en.wikipedia.org/wiki/List_of_military_time_zones">http://en.wikipedia.org/wiki/List_of_military_time_zones</a>. Lo que sigue son ejemplos de cómo deben ser los resultados del programa:</p>
-
- <ul>
- <li>Dada hora Zulu 1230 y zona A (UTC+1), el resultado debe ser 1330.</li>
- <li>Dada hora Zulu 1230 y zona N (UTC-1), el resultado debe ser 1130.</li>
- <li>Puerto Rico está en la zona militar Q (UTC-4), por lo tanto, cuando es 1800 en hora Zulu, son las 1400 en Puerto Rico.</li>
- </ul>
-
- <hr>
-
- <p><a href="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure9.png" target="_blank"><img src="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure9.png" alt="figure9.png" style="max-width:100%;"></a></p>
-
- <p><strong>Figura 9</strong> - Interfaz de la función <code>Zulu time</code>.</p>
-
- <hr>
- </li>
- </ul>
-
- <h4>
- <a id="user-content-instrucciones" class="anchor" href="#instrucciones" aria-hidden="true"><span class="octicon octicon-link"></span></a>Instrucciones</h4>
-
- <ol>
- <li>
- <p>Para cada una de las funciones descritas arriba, escribe en tu libreta las pruebas que harás para determinar la validez de cada implementación (Alpha, Beta, Gamma y Delta). Para cada función, piensa en los errores lógicos que el programador pudo haber cometido y escribe pruebas que determinen si se cometió ese error. Para cada prueba, escribe los valores que utilizarás y el resultado que esperas obtener.</p>
-
- <p>Por ejemplo, puedes organizar tus respuestas en una tabla como la que sigue:</p>
-
- <hr>
-
- <table>
- <thead>
- <tr>
- <th>3 Sorts</th>
- <th></th>
- <th></th>
- <th></th>
- <th></th>
- <th></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>Num</td>
- <td>Prueba</td>
- <td>Result Alpha</td>
- <td>Res. Beta</td>
- <td>Res. Gamma</td>
- <td>Res. Delta</td>
- </tr>
- <tr>
- <td>1</td>
- <td>"alce", "coyote", "zorro"</td>
- <td>"alce", "coyote", "zorro"</td>
- <td>....</td>
- <td>....</td>
- <td></td>
- </tr>
- <tr>
- <td>2</td>
- <td>"alce", "zorro", "coyote"</td>
- <td>"zorro", "alce", "coyote"</td>
- <td>....</td>
- <td>....</td>
- <td></td>
- </tr>
- <tr>
- <td>....</td>
- <td>....</td>
- <td>....</td>
- <td>....</td>
- <td>....</td>
- <td>....</td>
- </tr>
- </tbody>
- </table>
-
- <p><strong>Figura 10</strong> - Tabla para organizar los resultados de las pruebas.</p>
-
- <hr>
-
- <p>Puedes ver ejemplos de cómo organizar tus resultados <a href="http://i.imgur.com/ggDZ3TQ.png">aquí</a> y <a href="http://i.imgur.com/rpApVqm.png">aquí</a>. </p>
- </li>
- </ol>
-
- <h3>
- <a id="user-content-ejercicio-2-hacer-pruebas-a-mano" class="anchor" href="#ejercicio-2-hacer-pruebas-a-mano" aria-hidden="true"><span class="octicon octicon-link"></span></a>Ejercicio 2: Hacer pruebas "a mano"</h3>
-
- <p>El proyecto <code>testing</code> implementa varias versiones de cada una de las cuatro funciones simples que se decribieron en el Ejercicio 1. Algunas o todas las implementaciones pueden estar incorrectas. Tu tarea es, usando las pruebas que diseñaste en el Ejercicio 1, probar las versiones de cada función para determinar cuáles de ellas, si alguna, están implementadas correctamente.</p>
-
- <p>Este ejercicio <strong>NO requiere programación</strong>, debes hacer las pruebas <strong>sin mirar el código.</strong></p>
-
- <h4>
- <a id="user-content-instrucciones-1" class="anchor" href="#instrucciones-1" aria-hidden="true"><span class="octicon octicon-link"></span></a>Instrucciones</h4>
-
- <ol>
- <li><p>Carga a Qt el proyecto <code>Testing</code> haciendo doble "click" en el archivo <code>Testing.pro</code> en el directorio <code>Documents/eip/Testing</code> de tu computadora. También puedes ir a <code>http://bitbucket.org/eip-uprrp/testing</code> para descargar la carpeta <code>Testing</code> a tu computadora.</p></li>
- <li>
- <p>Configura el proyecto y corre el programa. Verás una pantalla similar a la siguiente:</p>
-
- <hr>
-
- <p><a href="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure11.png" target="_blank"><img src="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure11.png" alt="figure11.png" style="max-width:100%;"></a></p>
-
- <p><strong>Figura 11</strong> - Ventana para seleccionar la función que se va a probar.</p>
-
- <hr>
- </li>
- <li><p>Selecciona el botón de <code>3 Sorts</code> y obtendrás la interfaz de la Figura 5.</p></li>
- <li><p>La "Version Alpha" en la caja indica que estás corriendo la primera versión del algoritmo <code>3 Sorts</code>. Usa las pruebas que escribiste en el Ejercicio 1 para validar la "Version Alpha". Luego, haz lo mismo para las versiones Beta, Gamma y Delta. Escribe cuáles son las versiones correctas (si alguna) de la función y porqué. Recuerda que, para cada función, algunas o todas las implementaciones pueden estar incorrectas. Además, especifica cuáles pruebas te permitieron determinar las versiones que son incorrectas.</p></li>
- </ol>
-
- <h3>
- <a id="user-content-ejercicio-3-usar-assert-para-realizar-pruebas-unitarias" class="anchor" href="#ejercicio-3-usar-assert-para-realizar-pruebas-unitarias" aria-hidden="true"><span class="octicon octicon-link"></span></a>Ejercicio 3: Usar <code>assert</code> para realizar pruebas unitarias</h3>
-
- <p>Hacer pruebas "a mano" cada vez que corres un programa es una tarea que resulta "cansona" bien rápido. En los ejercicios anteriores lo hiciste para unas pocas funciones simples. !Imagínate hacer lo mismo para un programa complejo completo como un buscador o un procesador de palabras!</p>
-
- <p>Las <em>pruebas unitarias</em> ayudan a los programadores a validar códigos y simplificar el proceso de depuración ("debugging") a la vez que evitan la tarea tediosa de hacer pruebas a mano en cada ejecución.</p>
-
- <h4>
- <a id="user-content-instrucciones-2" class="anchor" href="#instrucciones-2" aria-hidden="true"><span class="octicon octicon-link"></span></a>Instrucciones:</h4>
-
- <ol>
- <li><p>En el menú de QT, ve a <code>Build</code> y selecciona <code>Clean Project "Testing"</code>.</p></li>
- <li><p>Carga a Qt el proyecto <code>UnitTests</code> haciendo doble "click" en el archivo <code>UnitTests.pro</code> en el directorio <code>Documents/eip/Testing</code> de tu computadora. También puedes ir a <code>http://bitbucket.org/eip-uprrp/testing</code> para descargar la carpeta <code>Testing</code> a tu computadora.</p></li>
- <li>
- <p>El proyecto solo contiene el archivo de código fuente <code>main.cpp</code>. Este archivo contiene cuatro funciones: <code>fact</code>, <code>isALetter</code>, <code>isValidTime</code>, y <code>gcd</code>, cuyos resultados son solo parcialmente correctos. </p>
-
- <p>Estudia la descripción de cada una de las funciones que aparece como comentarios antes el código de la función para saber la tarea que se espera haga la función.</p>
-
- <p>Tu tarea es escribir pruebas unitarias para cada una de las funciones para identificar los resultados erróneos. ** No necesitas reescribir las funciones para corregirlas. **</p>
-
- <p>Para la función <code>fact</code> se provee la función <code>test_fact()</code> como función de prueba unitaria. Si invocas esta función desde <code>main</code>, compilas y corres el programa debes obtener un mensaje como el siguiente:</p>
-
- <p><code>Assertion failed: (fact(2) == 2), function test_fact, file ../UnitTests/ main.cpp, line 69.</code></p>
-
- <p>Esto es suficiente para saber que la función <code>fact</code> NO está correctamente implementada. </p>
- </li>
- <li><p>Nota que, al fallar la prueba anterior, el programa no continuó su ejecución. Para poder probar el código que escribirás, comenta la invocación de <code>test_fact()</code> en <code>main</code>.</p></li>
- <li><p>Escribe una prueba unitaria llamada <code>test_isALetter</code> para la función <code>isALetter</code>. En la prueba unitaria escribe varias afirmaciones ("asserts") para probar algunos datos de entrada y sus valores esperados (mira la función <code>test_fact</code> para que te inspires). Invoca <code>test_isALetter</code> desde <code>main</code> y ejecuta tu programa. Si la función <code>isALetter</code> pasa las pruebas que escribiste, continúa escribiendo "asserts" y ejecutando tu programa hasta que alguno de los <code>asserts</code> falle. </p></li>
- <li><p>Comenta la invocación de <code>test_isALetter</code> en <code>main</code> para que puedas continuar con las otras funciones.</p></li>
- <li><p>Repite los pasos 5 y 6 paras las otras dos funciones, <code>isValidTime</code> y <code>gcd</code>. Recuerda que debes llamar a cada una de las funciones de prueba unitaria desde <code>main</code> para que corran. </p></li>
- </ol>
-
- <hr>
-
- <hr>
-
- <h2>
- <a id="user-content-entregas" class="anchor" href="#entregas" aria-hidden="true"><span class="octicon octicon-link"></span></a>Entregas</h2>
-
- <ol>
- <li><p>Utiliza "Entrega 1" en Moodle para entregar la tabla con las pruebas que diseñaste en el Ejercicio 1 y que completaste en el Ejercicio 2 con los resultados de las pruebas de las funciones.</p></li>
- <li><p>Utiliza "Entrega 2" en Moodle para entregar el archivo <code>main.cpp</code> que contiene las funciones <code>test_isALetter</code>, <code>test_isValidTime</code>, <code>test_gcd</code> y sus invocaciones. Recuerda utilizar buenas prácticas de programación, incluir el nombre de los programadores y documentar tu programa.</p></li>
- </ol>
-
- <hr>
-
- <hr>
-
- <h2>
- <a id="user-content-referencias" class="anchor" href="#referencias" aria-hidden="true"><span class="octicon octicon-link"></span></a>Referencias</h2>
-
- <p>[1] <a href="http://nifty.stanford.edu/2005/TestMe/">http://nifty.stanford.edu/2005/TestMe/</a></p>
-
- <hr>
-
- <hr>
-
- <hr>
-
- <p><a href="#markdown-header-testing-and-unit-testing">English</a> | <a href="#markdown-header-pruebas-y-pruebas-unitarias">Español</a></p>
-
- <h1>
- <a id="user-content-testing-and-unit-testing" class="anchor" href="#testing-and-unit-testing" aria-hidden="true"><span class="octicon octicon-link"></span></a>Testing and Unit Testing</h1>
-
- <p><a href="https://camo.githubusercontent.com/0130842aaebc4a0ecc5cb368730342cb64f26f62/687474703a2f2f64656d6f30352e636c6f7564696d6167652e696f2f732f726573697a652f3231352f692e696d6775722e636f6d2f44306c614935722e706e67" target="_blank"><img src="https://camo.githubusercontent.com/0130842aaebc4a0ecc5cb368730342cb64f26f62/687474703a2f2f64656d6f30352e636c6f7564696d6167652e696f2f732f726573697a652f3231352f692e696d6775722e636f6d2f44306c614935722e706e67" alt="" data-canonical-src="http://demo05.cloudimage.io/s/resize/215/i.imgur.com/D0laI5r.png" style="max-width:100%;"></a>
- <a href="https://camo.githubusercontent.com/df63e580b9f4f8f36e211d7d73119da4b9b9b6a5/687474703a2f2f64656d6f30352e636c6f7564696d6167652e696f2f732f726573697a652f3231352f692e696d6775722e636f6d2f6767445a3354512e706e67" target="_blank"><img src="https://camo.githubusercontent.com/df63e580b9f4f8f36e211d7d73119da4b9b9b6a5/687474703a2f2f64656d6f30352e636c6f7564696d6167652e696f2f732f726573697a652f3231352f692e696d6775722e636f6d2f6767445a3354512e706e67" alt="" data-canonical-src="http://demo05.cloudimage.io/s/resize/215/i.imgur.com/ggDZ3TQ.png" style="max-width:100%;"></a>
- <a href="https://camo.githubusercontent.com/b7887ab1723cd1330bddd867446d02940a4b83ce/687474703a2f2f64656d6f30352e636c6f7564696d6167652e696f2f732f726573697a652f3231352f692e696d6775722e636f6d2f563678466f30302e706e67" target="_blank"><img src="https://camo.githubusercontent.com/b7887ab1723cd1330bddd867446d02940a4b83ce/687474703a2f2f64656d6f30352e636c6f7564696d6167652e696f2f732f726573697a652f3231352f692e696d6775722e636f6d2f563678466f30302e706e67" alt="" data-canonical-src="http://demo05.cloudimage.io/s/resize/215/i.imgur.com/V6xFo00.png" style="max-width:100%;"></a></p>
-
- <p>As you have learned in previous labs, getting a program to compile is only a minor part of programming. The compiler will tell you if there are syntactical errors, but it isn't capable of detecting logical problems in your program. It's very important to test the program's functions to validate that they produce correct results.</p>
-
- <p>These tests can be performed by hand, this is, running the program multiple times, providing representative inputs and visually checking that the program outputs correct results. A more convenient way is to implement functions in the program whose sole purpose is to validate that other functions are working correctly. In this lab you will be practicing both testing methods.</p>
-
- <h2>
- <a id="user-content-objectives" class="anchor" href="#objectives" aria-hidden="true"><span class="octicon octicon-link"></span></a>Objectives:</h2>
-
- <ol>
- <li>Design tests to validate several programs “by-hand”, then use these tests to determine if the program works as expected. </li>
- <li>Create unit tests to validate functions, using the <code>assert</code> function.</li>
- </ol>
-
- <h2>
- <a id="user-content-pre-lab-1" class="anchor" href="#pre-lab-1" aria-hidden="true"><span class="octicon octicon-link"></span></a>Pre-Lab:</h2>
-
- <p>Before you get to the laboratory you should have:</p>
-
- <ol>
- <li><p>Reviewed the basic concepts related to testing and unit tests.</p></li>
- <li><p>Reviewed how to use the <code>assert</code> function to validate another function.</p></li>
- <li><p>Studied the concepts and instructions for this laboratory session.</p></li>
- <li><p>Taken the Pre-Lab quiz available in Moodle.</p></li>
- </ol>
-
- <hr>
-
- <hr>
-
- <h2>
- <a id="user-content-testing-a-function" class="anchor" href="#testing-a-function" aria-hidden="true"><span class="octicon octicon-link"></span></a>Testing a function</h2>
-
- <p>When we test a function's validity we should test cases that activate the various results the function could return.</p>
-
- <hr>
-
- <p><strong>Example 1:</strong> if you were to validate the function <code>isEven(unsigned int n)</code> that determines if a positive integer <em>n</em> is even, you should test the function using even and odd numbers. A set of tests for that function could be:</p>
-
- <table>
- <thead>
- <tr>
- <th>Test</th>
- <th>Expected Result</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><code>isEven(8)</code></td>
- <td>true</td>
- </tr>
- <tr>
- <td><code>isEven(7)</code></td>
- <td>false</td>
- </tr>
- </tbody>
- </table>
-
- <hr>
-
- <p><strong>Example 2:</strong> Suppose that a friend has created a function <code>unsigned int ageRange(unsigned int age)</code> that is supposed to return 0 if the age is between 0 and 5 (inclusive), 1 if the age is between 6 and 18 inclusive, and 2 if the age is above 18. A common source of errors in functions like this one are the values near to the limits of each range, for example, the number 5 can cause errors if the programmer did not use a correct comparison. One good set of tests for the <code>ageRange</code> function would be:</p>
-
- <table>
- <thead>
- <tr>
- <th>Test</th>
- <th>Expected Result</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><code>ageRange(5)</code></td>
- <td>0</td>
- </tr>
- <tr>
- <td><code>ageRange(2)</code></td>
- <td>0</td>
- </tr>
- <tr>
- <td><code>ageRange(6)</code></td>
- <td>1</td>
- </tr>
- <tr>
- <td><code>ageRange(18)</code></td>
- <td>1</td>
- </tr>
- <tr>
- <td><code>ageRange(17)</code></td>
- <td>1</td>
- </tr>
- <tr>
- <td><code>ageRange(19)</code></td>
- <td>2</td>
- </tr>
- <tr>
- <td><code>ageRange(25)</code></td>
- <td>2</td>
- </tr>
- </tbody>
- </table>
-
- <hr>
-
- <h3>
- <a id="user-content-assert-function" class="anchor" href="#assert-function" aria-hidden="true"><span class="octicon octicon-link"></span></a><code>Assert</code> Function:</h3>
-
- <p>The <code>assert(bool expression)</code> function can be used as a rudimentary tool to validate functions. <code>assert</code> has a very powerful yet simple functionality. If the expression that we place between the <code>assert</code> parenthesis is <em>true</em>, the function allows the program to continue onto the next instruction. Otherwise, if the expression we place between the parenthesis is <em>false</em>, the <code>assert</code> function causes the program to terminate and prints an error message on the terminal that informs the user about the <code>assert</code> instruction that failed.</p>
-
- <p>For example, the following program will run from start to finish without problems since every expression included in the assert's parentheses evaluates to <em>true</em>.</p>
-
- <hr>
-
- <div class="highlight highlight-cpp"><pre>#<span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds"><</span>iostream<span class="pl-pds">></span></span>
- #<span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds"><</span>cassert<span class="pl-pds">></span></span>
- <span class="pl-k">using</span> <span class="pl-k">namespace</span> <span class="pl-en">std</span><span class="pl-k">;</span>
-
- <span class="pl-k">int</span> <span class="pl-en">main</span>() {
- <span class="pl-k">int</span> i = <span class="pl-c1">10</span>, j = <span class="pl-c1">15</span>;
- <span class="pl-c1">assert</span>(i == <span class="pl-c1">10</span>);
- <span class="pl-c1">assert</span>(j == i + <span class="pl-c1">5</span>);
- <span class="pl-c1">assert</span>(j != i);
- <span class="pl-c1">assert</span>( (j < i) == <span class="pl-c1">false</span>);
- cout << <span class="pl-s"><span class="pl-pds">"</span>That's all, folks!<span class="pl-pds">"</span></span> << endl;
- <span class="pl-k">return</span> <span class="pl-c1">0</span>;
- }
- </pre></div>
-
- <p><strong>Figure 1.</strong> Example of a program that passes all of the <code>assert</code> tests.</p>
-
- <hr>
-
- <p>The following program will not run to completion because the second <code>assert</code> (<code>assert(j == i);</code>) contains an expression (<code>j==i</code>) that evaluates to <em>false</em>.</p>
-
- <hr>
-
- <div class="highlight highlight-cpp"><pre>
- #<span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds"><</span>iostream<span class="pl-pds">></span></span>
- #<span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds"><</span>cassert<span class="pl-pds">></span></span>
- <span class="pl-k">using</span> <span class="pl-k">namespace</span> <span class="pl-en">std</span><span class="pl-k">;</span>
-
- <span class="pl-k">int</span> <span class="pl-en">main</span>() {
- <span class="pl-k">int</span> i = <span class="pl-c1">10</span>, j = <span class="pl-c1">15</span>;
- <span class="pl-c1">assert</span>(i == <span class="pl-c1">10</span>);
- <span class="pl-c1">assert</span>(j == i);
- <span class="pl-c1">assert</span>(j != i);
- <span class="pl-c1">assert</span>( (j < i) == <span class="pl-c1">false</span>);
- cout << <span class="pl-s"><span class="pl-pds">"</span>That's all, folks!<span class="pl-pds">"</span></span> << endl;
- <span class="pl-k">return</span> <span class="pl-c1">0</span>;
- }
- </pre></div>
-
- <p><strong>Figure 2.</strong> Example of a program that does not pass an <code>assert</code> test.</p>
-
- <hr>
-
- <p>When the program is run, instead of getting the phrase <code>”That's all, folks!”</code> in the terminal, we will obtain something like:</p>
-
- <p><code>Assertion failed: (j == i), function main, file ../program01/main.cpp, line 8.</code></p>
-
- <p>The program will not execute the remaining instructions after line 8.</p>
-
- <h4>
- <a id="user-content-how-to-use-assert-to-validate-functions" class="anchor" href="#how-to-use-assert-to-validate-functions" aria-hidden="true"><span class="octicon octicon-link"></span></a>How to use assert to validate functions?</h4>
-
- <p>Suppose that you want to automate the validation of the <code>ageRange</code>. One way to do it is by implementing and calling a function that calls the <code>ageRange</code> function with different arguments and verifies that each returned value is equal to the expected result. If the <code>ageRange</code> function returns a value that is not expected, the testing function aborts the program and reports the test that failed. The following illustrates a function to test the <code>ageRange</code> function. Observe that it consists of one assert per each of the tests we had listed earlier. </p>
-
- <hr>
-
- <div class="highlight highlight-cpp"><pre><span class="pl-k">void</span> <span class="pl-en">test_ageRange</span>() {
- <span class="pl-c1">assert</span>(<span class="pl-c1">ageRange</span>(<span class="pl-c1">5</span>) == <span class="pl-c1">0</span>);
- <span class="pl-c1">assert</span>(<span class="pl-c1">ageRange</span>(<span class="pl-c1">2</span>) == <span class="pl-c1">0</span>);
- <span class="pl-c1">assert</span>(<span class="pl-c1">ageRange</span>(<span class="pl-c1">6</span>) == <span class="pl-c1">1</span>);
- <span class="pl-c1">assert</span>(<span class="pl-c1">ageRange</span>(<span class="pl-c1">18</span>) == <span class="pl-c1">1</span>);
- <span class="pl-c1">assert</span>(<span class="pl-c1">ageRange</span>(<span class="pl-c1">17</span>) == <span class="pl-c1">1</span>);
- <span class="pl-c1">assert</span>(<span class="pl-c1">ageRange</span>(<span class="pl-c1">19</span>) == <span class="pl-c1">2</span>);
- <span class="pl-c1">assert</span>(<span class="pl-c1">ageRange</span>(<span class="pl-c1">25</span>) == <span class="pl-c1">2</span>);
- cout << <span class="pl-s"><span class="pl-pds">"</span>ageRange passed all tests!!!<span class="pl-pds">"</span></span> << endl;
- }</pre></div>
-
- <p><strong>Figure 3.</strong> Example of a test function using <code>assert</code>.</p>
-
- <hr>
-
- <hr>
-
- <h2>
- <a id="user-content-laboratory-session" class="anchor" href="#laboratory-session" aria-hidden="true"><span class="octicon octicon-link"></span></a>Laboratory Session:</h2>
-
- <h3>
- <a id="user-content-exercise-1-designing-tests-by-hand" class="anchor" href="#exercise-1-designing-tests-by-hand" aria-hidden="true"><span class="octicon octicon-link"></span></a>Exercise 1: Designing tests by hand</h3>
-
- <p>In this exercise you will practice how to design tests to validate functions, using only the function's description and the graphical user interface that is used interact with the function.</p>
-
- <p>The exercise <strong>DOES NOT require programming</strong>, it only requires that you understand the function’s description, and your ability to design tests. This exercise and Exercise 2 are an adaptation of the exercise in [1].</p>
-
- <p><strong>Example 3</strong> Suppose that a friend provides you with a program. She makes sure the program solves the following problem:</p>
-
- <p><code>"given three integers, it displays the max value".</code></p>
-
- <p>Suppose that the program has an interface like the following:</p>
-
- <hr>
-
- <p><a href="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure4.png" target="_blank"><img src="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure4.png" alt="figure4.png" style="max-width:100%;"></a></p>
-
- <p><strong>Figure 4</strong> - Interface for a program that finds the max value out of three integers.</p>
-
- <hr>
-
- <p>You could determine if the program provides valid results <strong>without analyzing the source code</strong>. For example, you could try the following cases:</p>
-
- <ul>
- <li>a = 4, b = 2, c = 1; expected result: 4</li>
- <li>a = 3, b = 6, c = 2; expected result: 6</li>
- <li>a = 1, b = 10, c = 100; expected result: 100</li>
- </ul>
-
- <p>If one of these three cases does not have the expected result, your friend's program does not work. On the other hand, if the three cases work, then the program has a high probability of being correct.</p>
-
- <h4>
- <a id="user-content-functions-to-validate" class="anchor" href="#functions-to-validate" aria-hidden="true"><span class="octicon octicon-link"></span></a>Functions to validate</h4>
-
- <p>In this exercise you will be designing tests to validate various versions of the functions that are described below. Each one of the functions has four versions, "Alpha", "Beta", "Gamma" and "Delta".</p>
-
- <ul>
- <li>
- <p><strong>3 Sorts:</strong> a function that receives three strings and orders them in lexicographic (alphabetical) order. For example, given <code>giraffe</code>, <code>fox</code>, and <code>coqui</code>, it would order them as: <code>coqui</code>, <code>fox</code>, and <code>giraffe</code>. To simplify the exercise, we will be using strings with lowercase <strong>letters</strong>. Figure 5 shows the function's interface. Notice there is a menu to select the implemented version.</p>
-
- <hr>
-
- <p><a href="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure5.png" target="_blank"><img src="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure5.png" alt="figure5.png" style="max-width:100%;"></a></p>
-
- <p><strong>Figure 5</strong> - Interface for the <code>3 Sorts</code> function.</p>
-
- <hr>
- </li>
- <li>
- <p><strong>Dice:</strong> when the user presses the <code>Roll them!</code> button, the program generates two random integers between 1 and 6. The program informs the sum of the two random numbers.</p>
-
- <hr>
-
- <p><a href="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure6.png" target="_blank"><img src="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure6.png" alt="figure6.png" style="max-width:100%;"></a></p>
-
- <p><strong>Figure 6</strong> - Interface for the <code>Dice</code> function.</p>
-
- <hr>
- </li>
- <li>
- <p><strong>Rock, Paper, Scissors:</strong> each one of the players enters their play and the program informs who the winner is. Figure 7 shows the options where one object beats the other. The game's interface is shown in Figure 8.</p>
-
- <hr>
-
- <p><a href="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure7.jpg" target="_blank"><img src="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure7.jpg" alt="figure7.jpg" style="max-width:100%;"></a></p>
-
- <p><strong>Figure 7</strong> - Ways to win in "Rock, paper, scissors".</p>
-
- <hr>
-
- <p><a href="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure8.png" target="_blank"><img src="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure8.png" alt="figure8.png" style="max-width:100%;"></a></p>
-
- <p><strong>Figure 8</strong> - Interface for the <code>Rock, Paper, Scissors</code> function.</p>
-
- <hr>
- </li>
- <li>
- <p><strong>Zulu time:</strong> Given a time in Zulu format (time at the Greenwich Meridian) and the military zone in which the user wants to know the time, the program shows the time in that zone. The format for the entry data is in the 24 hour format <code>####</code>, for example <code>2212</code> would be 10:12pm. The list of valid military zones can be found in <a href="http://en.wikipedia.org/wiki/List_of_military_time_zones">http://en.wikipedia.org/wiki/List_of_military_time_zones</a>. The following are examples of some valid results:</p>
-
- <ul>
- <li>Given Zulu time 1230 and zone A (UTC+1), the result should be 1330.</li>
- <li>Given Zulu time 1230 and zone N (UTC-1), the result should be 1130.</li>
- <li>Puerto Rico is in military zone Q (UTC-4), therefore, when its 1800 in Zulu time, it's 1400 in Puerto Rico.</li>
- </ul>
-
- <hr>
-
- <p><a href="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure9.png" target="_blank"><img src="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure9.png" alt="figure9.png" style="max-width:100%;"></a></p>
-
- <p><strong>Figure 9</strong> - Interface for the <code>Zulu time</code> function.</p>
-
- <hr>
- </li>
- </ul>
-
- <h4>
- <a id="user-content-instructions" class="anchor" href="#instructions" aria-hidden="true"><span class="octicon octicon-link"></span></a>Instructions</h4>
-
- <ol>
- <li>
- <p>For each of the functions described above, write in your notebook the tests that you will do to determine the validity of each implementation (Alpha, Beta, Gamma and Delta). For each function, think of the logical errors that the programmer could have made and write tests that determine if these errors were made. For each test, write the values that you will use and the expected result.</p>
-
- <p>For example, you could organize your answers in a table like the following:</p>
-
- <hr>
-
- <table>
- <thead>
- <tr>
- <th>3 Sorts</th>
- <th></th>
- <th></th>
- <th></th>
- <th></th>
- <th></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>Num</td>
- <td>Test</td>
- <td>Alpha Result</td>
- <td>Beta Result</td>
- <td>Gamma Result</td>
- <td>Delta Result</td>
- </tr>
- <tr>
- <td>1</td>
- <td>"deer", "coyote", "fox"</td>
- <td>"coyote", "deer", "fox"</td>
- <td>....</td>
- <td>....</td>
- <td></td>
- </tr>
- <tr>
- <td>2</td>
- <td>"deer", "fox", "coyote"</td>
- <td>"fox", "deer", "coyote"</td>
- <td>....</td>
- <td>....</td>
- <td></td>
- </tr>
- <tr>
- <td>....</td>
- <td>....</td>
- <td>....</td>
- <td>....</td>
- <td>....</td>
- <td>....</td>
- </tr>
- </tbody>
- </table>
-
- <p><strong>Figure 10</strong> - Table to organize the test results.</p>
-
- <hr>
- </li>
- </ol>
-
- <p>You can see examples of how to organize your results <a href="http://i.imgur.com/ggDZ3TQ.png">here</a> and <a href="http://i.imgur.com/rpApVqm.png">here</a>.</p>
-
- <h3>
- <a id="user-content-exercise-2-doing-tests-by-hand" class="anchor" href="#exercise-2-doing-tests-by-hand" aria-hidden="true"><span class="octicon octicon-link"></span></a>Exercise 2: Doing tests “by hand”</h3>
-
- <p>The <code>testing</code> project implements several versions of each of the four functions that were described in Exercise 1. Some or all of the implementations could be incorrect. Your task is, using the tests you designed in Exercise 1, to test the versions for each function to determine which of them, if any, are implemented correctly.</p>
-
- <p>This exercise <strong>DOES NOT require programming</strong>, you should make the tests <strong>without looking at the code.</strong></p>
-
- <h4>
- <a id="user-content-instructions-1" class="anchor" href="#instructions-1" aria-hidden="true"><span class="octicon octicon-link"></span></a>Instructions</h4>
-
- <ol>
- <li><p>Load the <code>Testing</code> project onto Qt by double clicking the <code>Testing.pro</code> file in the <code>Documents/eip/Testing</code> directory on your computer. You can also go to <code>http://bitbucket.org/eip-uprrp/testing</code> to downloaded the <code>Testing</code> folder on your computer.</p></li>
- <li>
- <p>Configure the project and run the program. You will see a window similar to the following:</p>
-
- <hr>
-
- <p><a href="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure11.png" target="_blank"><img src="/Users/Ivelisse/Dropbox/eip/EIP-REVISION-VERANO/Testing/Testing-Edited-WithSolutions-July2015/images/figure11.png" alt="figure11.png" style="max-width:100%;"></a></p>
-
- <p><strong>Figure 11</strong> - Window to select the function that will be tested.</p>
-
- <hr>
- </li>
- <li><p>Select the button for <code>3 Sorts</code> and you will obtain the interface in Figure 5.</p></li>
- <li><p>The "Alpha Version" in the box indicates that you're running the first version of the <code>3 Sorts</code> algorithm. Use the tests that you wrote in Exercise 1 to validate the "Alpha Version". Afterwards, do the same with the Beta, Gamma and Delta versions. Write down which are the correct versions of the function (if any), and why. Remember that, for each function, some or all of the implementations could be incorrect. Additionally, specify which tests allowed you to determine the incorrect versions.</p></li>
- </ol>
-
- <h3>
- <a id="user-content-exercise-3-using-assert-to-make-unit-tests" class="anchor" href="#exercise-3-using-assert-to-make-unit-tests" aria-hidden="true"><span class="octicon octicon-link"></span></a>Exercise 3: Using <code>assert</code> to make unit tests</h3>
-
- <p>Doing tests by hand each time you run a program is a tiresome task. In the previous exercises you did it for a few simple functions. Imagine doing the same for a complex program like a search engine or a word processor.</p>
-
- <p><em>Unit tests</em> help programmers validate code and simplify the process of debugging while avoiding having to do these tests by hand in each execution.</p>
-
- <h4>
- <a id="user-content-instructions-2" class="anchor" href="#instructions-2" aria-hidden="true"><span class="octicon octicon-link"></span></a>Instructions:</h4>
-
- <ol>
- <li><p>In the Qt menu, go to <code>Build</code> and select <code>Clean Project "Testing"</code>.</p></li>
- <li><p>Load the <code>UnitTests</code> project onto Qt by double clicking the <code>UnitTests.pro</code> file in the <code>Documents/eip/Testing</code> directory on your computer. You can also go to <code>http://bitbucket.org/eip-uprrp/testing</code> to download the <code>Testing</code> folder on your computer.</p></li>
- <li>
- <p>The project only contains the source code file <code>main.cpp</code>. This file contains four functions: <code>fact</code>, <code>isALetter</code>, <code>isValidTime</code>, and <code>gcd</code>, whose results are only partially correct.</p>
-
- <p>Study the description of each function that appears as a comment before the function's code to understand the task that the function is supposed to carry out.</p>
-
- <p>Your task is to write unit tests for each of the functions to identify the erroneous results. <strong>You do not need to rewrite the functions to correct them.</strong></p>
-
- <p>For the <code>fact</code> function, a <code>test_fact()</code> is provided as a unit test function. If you invoke the function from <code>main</code>, compile and run the program you should obtain a message like the following:</p>
-
- <p><code>Assertion failed: (fact(2) == 2), function test_fact, file ../UnitTests/ main.cpp, line 69.</code></p>
-
- <p>This is evidence enough to establish that the <code>fact</code> function is NOT correctly implemented.</p>
- </li>
- <li><p>Notice that, by failing the previous test, the program did not continue its execution. To test the code you will write, comment the <code>test_fact()</code> call in <code>main</code>.</p></li>
- <li><p>Write a unit test called <code>test_isALetter</code> for the <code>isALetter</code> function. Write various asserts in the unit test to try some data and its expected values (use the <code>test_fact</code> function for inspiration). Invoke <code>test_isALetter</code> from <code>main</code> and execute your program. If the <code>isALetter</code> function passes the test you wrote, continue writing asserts and executing the program until one of them fails.</p></li>
- <li><p>Comment the <code>test_isALetter</code> call in <code>main</code> so you can continue with the other functions.</p></li>
- <li><p>Repeat the steps in 5 and 6 for the other two functions, <code>isValidTime</code> and <code>gcd</code>. Remember that you should call each of the unit test functions from <code>main</code> for them to run. </p></li>
- </ol>
-
- <hr>
-
- <hr>
-
- <h2>
- <a id="user-content-deliverables" class="anchor" href="#deliverables" aria-hidden="true"><span class="octicon octicon-link"></span></a>Deliverables</h2>
-
- <ol>
- <li><p>Use "Deliverables 1" in Moodle to hand in the table with the tests you designed in Exercise 1 and that you completed in Exercise 2 with the results from the function tests.</p></li>
- <li><p>Use "Deliverables 2" in Moodle to hand in the <code>main.cpp</code> file that contains the <code>test_isALetter</code>, <code>test_isValidTime</code>, <code>test_gcd</code> functions and their calls. Remember to use good programming techniques, include the name of the programmers involved and document your program.</p></li>
- </ol>
-
- <hr>
-
- <hr>
-
- <h2>
- <a id="user-content-references" class="anchor" href="#references" aria-hidden="true"><span class="octicon octicon-link"></span></a>References</h2>
-
- <p>[1] <a href="http://nifty.stanford.edu/2005/TestMe/">http://nifty.stanford.edu/2005/TestMe/</a></p>
-
- <hr>
-
- <hr>
-
- <hr>
- </article></body></html>
|