This is very comprehensive testing. Impressive.
Thank you for sharing, Thierry.
>Hi Dmitry,
>
>I'll probably answer aside your question, however here is what we do at FoxInCloud in terms of QA (probably no breaking news):
>
>1- move as much code as possible into separate modules (class, procedure, function)
>
>2- we have developed a unit test routine that automatically tests a module based on a name convention; to test 'module', we write:
>
>procedure module
> bla
> bla
>endproc
>
>procedure module_test
>
>local loTest as abUnitTest of abDev.prg, laOps[1]
>loTest = newobject('abUnitTest', 'abDev.prg')
>
>loTest.Test(4, @m.laOps, 'toto = alias.field +fonction(alias.tutu)')
>
>* m.loTest.coverageSet()
>
>loTest.Test(5, @m.laOps, 'toto = alias.field +fonction(alias.tutu + 5)')
>loTest.assert('toto', m.laOps[1])
>loTest.assert('alias.field', m.laOps[2])
>loTest.assert('fonction', m.laOps[3])
>loTest.assert('alias.tutu', m.laOps[4])
>loTest.assert('5', m.laOps[5])
>
>return loTest.Result()
>endproc
>
>
>We find it interesting to write the test right next to the module itself: this way we can very quickly make sure every module has its associated test (we do TDD).
>
>3- to run this unit test we just
>
>do module_test in xxx.prg
>
>
>we get this result on _screen and in a 'module.tst' file (in French):
>
>25/08/17 09:30:27
>Module : C:\Program Files\VFP9\Tools\AB\abtxt.fxp!AOPERANDS()
>Résultats de 2 tests dont 0 avec coverage dans 'c:\users\thierrynivelet\appdata\roaming\microsoft\visual foxpro 9\AB\AOPERANDS.cov.log'
>Temps d'exécution sans coverage Mini | Moyen | Maxi : 0,020 ms| 0,020 ms| 0,030 ms
>---------------------------------------------
>2 tests réalisés avec succès
>
>
>Notice we also get the execution time and, of course, the 'module.tst' file has the full test history for this module.
>
>We can also trigger a coverage trace by writing:
>
>m.loTest.coverageSet()
>
>
>4- to run all tests in a procedure file (eg. xxx.prg), we just do
>
>? xxx()
>
>
>because we have this code at the beginning of all procedure files:
>
>return abUnitTests()
>
>
>abUnitTests() identifies all test modules in the procedure file and runs them; it collects the results returned by each test module (return loTest.Result())
>
>Then we have a "layer level" program that runs all procedure files:
>
>* --------------------------------------------------
>PROCEDURE AB_Tests
>
>local success as Boolean;
>, loAsserts as abSet of abDev.prg;
>, laPrg[1], lcPrg
>
>success = aABprgs(@m.laPrg) > 0
>if m.success
>
> CLEAR
> loAsserts = abSet('ASSERTS', 'OFF')
> for each lcPrg in m.laPrg
> success = Evaluate(JustStem(m.lcPrg) + '()') and m.success
> endfor
>endif
>
>wait clear
>return m.success
>endproc
>
>
>
>The result is a flight pre-check saying that each individual module performs as expected.
>
>Of course, and unfortunately, we still need human testing (<g>).
>
>>Hi,
>>I have been in business long time and I used to do 0 (zero) testing before releasing new updates. And invariably, as soon as the app would get in the hands of a customer, it would crash. I even remember the times - before internet - when I had to ship a diskette overnight or send it with a taxi.
>>
>>Now I am doing much more testing, even though updating is much simpler.
>>
>>Which brings me to a question. I don't have a QA, so I am it :)
>>
>>Currently I am doing a refactoring where 3 SQL Select statements are replaced with 1. The SQL Select is very important because it is part of the important Business unit of the application. The way I am testing it as follows:
>>1. I created a list of test cases (various possibilities of data)
>>2. Run this new SQL Select and BROWS the resulting cursor
>>3. Run the old 3 SQL Selects against the same data and BROWSE resulting cursor.
>>4. Compare - row-by-row the two cursors.
>>
>>How else would you suggest that I test this change?
"The creative process is nothing but a series of crises." Isaac Bashevis Singer
"My experience is that as soon as people are old enough to know better, they don't know anything at all." Oscar Wilde
"If a nation values anything more than freedom, it will lose its freedom; and the irony of it is that if it is comfort or money that it values more, it will lose that too." W.Somerset Maugham