Thread overview
unittest behaviour
2 days ago
DLearner
2 days ago
H. S. Teoh
2 days ago
monkyyy
11 hours ago
DLearner
11 hours ago
H. S. Teoh
9 hours ago
DLearner
6 hours ago
monkyyy
6 hours ago
monkyyy
1 day ago
user1234
2 days ago

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.

2 days ago
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.
2 days ago

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)

1 day ago

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:

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".

11 hours ago

On Sunday, 15 December 2024 at 20:30:21 UTC, monkyyy wrote:

>

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)

What is wrong with changing the specification of unittest so that it recompiles/reexecutes the associated source on every unittest {} block?

That way, there would be no alteration in behaviour if the source was 'pure', but you would have flexibility if you wanted to test source that was (intentionally) 'stateful'.

11 hours ago
On Tue, Dec 17, 2024 at 07:16:55PM +0000, DLearner via Digitalmars-d-learn wrote: [...]
> What is wrong with changing the specification of unittest so that it recompiles/reexecutes the associated source on every unittest {} block?

That means the compiler will have to rerun your program once per unittest.  That means your OS has to create a new process per unittest. If you have a lot of unittests, that adds a huge amount of overhead.


> That way, there would be no alteration in behaviour if the source was 'pure', but you would have flexibility if you wanted to test source that was (intentionally) 'stateful'.
[...]

It still does not solve the problem of unittests with side-effects, like file or network I/O.


T

-- 
Did you hear about the kidnapping at school today?  Everything's OK now -- he woke up.
9 hours ago

On Tuesday, 17 December 2024 at 19:56:32 UTC, H. S. Teoh wrote:
[...]

>

That means the compiler will have to rerun your program once per unittest. That means your OS has to create a new process per unittest. If you have a lot of unittests, that adds a huge amount of overhead.

Agreed, but only an issue when testing, not in production.

[...]

>

It still does not solve the problem of unittests with side-effects, like file or network I/O.

To me, it is unreasonable to expect unittest (as a part of the compiler suite) to establish/reset those parts of the environment outside of the program source code (like creating/restoring test files etc).
I regard that as something that is the programmer's responsibility [perhaps by writing a script that performs those tasks, and calling that script within the unittest].

6 hours ago

On Tuesday, 17 December 2024 at 21:31:13 UTC, DLearner wrote:

>

On Tuesday, 17 December 2024 at 19:56:32 UTC, H. S. Teoh wrote:
[...]

>

That means the compiler will have to rerun your program once per unittest. That means your OS has to create a new process per unittest. If you have a lot of unittests, that adds a huge amount of overhead.

Agreed, but only an issue when testing, not in production.

testing is where compile times matter

Only need to ship code once, ideally I compile code every few seconds

6 hours ago

On Tuesday, 17 December 2024 at 19:16:55 UTC, DLearner wrote:

>

On Sunday, 15 December 2024 at 20:30:21 UTC, monkyyy wrote:

>

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)

What is wrong with changing the specification of unittest so that it recompiles/reexecutes the associated source on every unittest {} block?

Sounds also slow