For floating points it would be good to also have something related to unit
of least precision like I think it exists in google tests:

assert: aFloat isWithin: anInteger ulpFrom: anotherFloat
    ^(aFloat - anotherFloat) abs <= (anotherFloat ulp max: aFloat ulp)

It's testing if the result are the same with a tolerance on least
significant bits.
(anotherFloat ulp max: aFloat ulp) is not really necessary, it's only for
making the comparison symmetric.
indeed, 2 and 2 predecessor do not have the same exponent, so do not have
the same ulp.
If we don't have symmetry, then
    self assert: 2.0 predecessor predecessor isWithin: 1 ulpFrom: 2.0.
might differ from:
    self assert: 2.0 isWithin: 1 ulpFrom: 2.0 predecessor predecessor .

Note that the this message cannot be used to test for zero result (because
0.0 ulp is the smallest denormal).
For example:
    self assert: 2.0 - 2.0 predecessor isWithin: 4 ulpFrom: 0.0.
would anwer false, but it makes no sense!
One should write
    self assert: 2.0 isWithin: 4 ulpFrom: 2.0 predecessor.

2016-09-03 9:22 GMT+02:00 stepharo <[email protected]>:

> Denis
>
> can we also have
>
> assert: aNumber withPrecision: precision equals: otherNumber
>
>       self
>       assert: (aNumber round: precision)
>       equals: otherNumber
>
> assert: aNumber closeTo: otherNumber
>
>       assert: aNumber withPrecision: self defaultPrecision equals: otherNumber
>
> defaultPrecision
>       ^ 2
>
>
>
> Le 31/8/16 à 14:10, Denis Kudriashov a écrit :
>
> Hi.
>
> I am working on SUnit improvements. I open issue 19015
> <https://pharo.fogbugz.com/f/cases/19015/Tests-should-never-hang-and-leave-forked-processes-live>.
> Slice is inbox which waits your review and feedback.
> I was trying to address three problems:
>
> *1) Tests should never hang. They should be always executed within time
> limit.*
>
> I give them 10 minutes for now to not change existing behaviour of tests.
> At next step it should be  really reduced to ~100 milliseconds (?).
> Any TestCase could redefine time limit by method #defaultTimeLimit.
> Or it could be specified directly in test code by
> self timeLimit: 10 seconds
> (could be changed at any time of test execution).
>
>
> would be good
>
>
> To implement this logic special watch dog process is running for given
> test suite to control execution time of tests. It is single process for
> full test suite.
>
> *2) When test completes all forked processes should be terminated.*
>
> If your tested code produced zombie processes SUnit will take care about
> destroying all such garbage.
> (it not means that you don't need to clean table in #tearDown but any code
> could be broken and running tests should not produce dirty system).
>
> Yes!!!
>
> *3) Any failures inside forked processes should not spawn debugger while
> running tests.*
> Only when we debug tests we need debugger on forked failed processes.
> During normal run SUnit should prevent such "background debuggers" and
> mark such tests as failed.
>
> Definitevely. Now when we execute tests from the testRunner and nautilus
> we should get the debugger, right?
>
>
> To implement this behaviour SUnit will handle errors from forked processes
> by suspending them and collecting them in special collection.
> I introduce TestFailedByForkedProcess error to signal these kind of
> problems at the end of tests. This error is resumable and resume will opens
> debuggers of suspended failures (in fact it will resume suspended
> processes).
> So to debug background failures you will need extra Proceed action on
> debugger when TestFailedByForkedProcess is signalled.
> But in normal run such tests will be just failed by
> TestFailedByForkedProcess error.
>
> We should really write a little doc so that I can add it to the Sunit
> Chapter.
>
>
>
>
> *Now details on how it is done:*
>
> I introduce special process specific variable CurrentExecutionEnvironment.
> It is not installed by default and as default value it returns
> DefaultExecutionEnvironment instance.
> This variable is inheritable. If your install concrete environment into
> process it will be installed to any child process.
>
> So value of variable is instance of ExecutionEnvironment subclasses and
> you can install it by:
>
> anYourExecutionEnvironment beActiveDuring: aBlock
>
>
> When block completes previous environment is restored.
> For default environment there is class side method:
>
> DefaultExecutionEnvironment beActiveDuring: aBlock
>
>
> And to reset current environment to default:
>
> DefaultExecutionEnvironment beActive.
>
>
> SUnit introduces TestExecutionEnvironment which implements all described
> behaviour for time limits and forked processes.
> To activate environment there is new method #runCaseManaged. And submitted
> slice uses it instead of simple runCase.
>
> TestCase>>runCaseManaged
> CurrentExecutionEnvironment runTestCase: self
>
>
> DefaultExecutionEnvironment will install new TestExecutionEnvironment and
> delegate processing to it. And if TestExecutionEnvironment is already
> active it will just process new test case.
>
> Now monkey has problem in checking slice (annoying timeout for loading).
> So I can't see real system impact. But it should not stop you from review
> :))
> I think it is very important features for all our tests. And environment
> idea will lead to very interesting future.
>
>
> Indeed!
>
>
> Best regards,
> Denis
>
>
>

Reply via email to