www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - unittest behaviour

reply DLearner <bmqazwsx123 gmail.com> writes:
Please consider:

```
size_t foo() {
    static size_t var1 = 1;

    var1 = var1 + 1;
    return var1;
}

unittest {

    assert(foo() == 2);
    assert(foo() == 3);
}

```

which works as expected.

But

```
size_t foo1() {
    static size_t var1 = 1;

    var1 = var1 + 1;
    return var1;
}

unittest {
    assert(foo1() == 2);
}

unittest {
    assert(foo1() == 2);
}

```

Fails on the second unittest.

I appreciate this behaviour matches the docs (so not a bug), but 
is it desirable?

To me, as a test harness, a umittest block should be a completely 
fresh-from-scratch invocation of the code inside the block, and 
thus not depend on the result/effects of any previous unittest.
Dec 15
next sibling parent "H. S. Teoh" <hsteoh qfbox.info> writes:
On Sun, Dec 15, 2024 at 08:45:22AM +0000, DLearner via Digitalmars-d-learn
wrote:
[...]
 I appreciate this behaviour matches the docs (so not a bug), but is it
 desirable?
 
 To me, as a test harness, a umittest block should be a completely
 fresh-from-scratch invocation of the code inside the block, and thus
 not depend on the result/effects of any previous unittest.
That's for you, the programmer, to ensure. Using a static variable breaks this assumption. As does a whole bunch of other things you could do that have side-effects, such as file I/O or network traffic. So if you want your code to be unittest-able in an encapsulated way, refactor it so that it doesn't have side-effects of this kind. T -- Caffeine underflow. Brain dumped.
Dec 15
prev sibling next sibling parent monkyyy <crazymonkyyy gmail.com> writes:
On Sunday, 15 December 2024 at 08:45:22 UTC, DLearner wrote:
 I appreciate this behaviour matches the docs (so not a bug), 
 but is it desirable?
yes, the alternative would be that unittests attempt to undo themselves, and that would make bugs horrible horrible bugs or executable clear global scope and stack effectively restarting the program, this could be incredibly slow if you have big arrays in global scope and then hundards of small unrelated unittests(which btw you do, the std has plenty and I think the run time also injects some)
Dec 15
prev sibling parent user1234 <user1234 12.de> writes:
On Sunday, 15 December 2024 at 08:45:22 UTC, DLearner wrote:
 Please consider:

 ```
 size_t foo() {
    static size_t var1 = 1;

    var1 = var1 + 1;
    return var1;
 }

 unittest {

    assert(foo() == 2);
    assert(foo() == 3);
 }

 ```

 which works as expected.

 But

 ```
 size_t foo1() {
    static size_t var1 = 1;

    var1 = var1 + 1;
    return var1;
 }

 unittest {
    assert(foo1() == 2);
 }

 unittest {
    assert(foo1() == 2);
 }

 ```

 Fails on the second unittest.

 I appreciate this behaviour matches the docs (so not a bug), 
 but is it desirable?
Yes. Remember that you have the function attribute `pure` [[1]]. It would have avoided the problem.. for instance: ```d size_t foo1() { static size_t var1 = 1; var1 = var1 + 1; return var1; } pure unittest { assert(foo1() == 2); } pure unittest { assert(foo1() == 2); } ``` refuses to compile with the following errors
 test.d(9,15): Error: `pure` function 
 `temp_7F58D0140210.__unittest_L8_C6` cannot call impure 
 function `temp_7F58D0140210.foo1`
 test.d(13,15): Error: `pure` function 
 `temp_7F58D0140210.__unittest_L12_C6` cannot call impure 
 function `temp_7F58D0140210.foo1`
With `pure` that you would have seen the problem, that is "oh, the global state". [1]: https://dlang.org/spec/function.html#pure-functions
Dec 16