March 22, 2018
On Thursday, 22 March 2018 at 17:09:55 UTC, Marco Leise wrote:
> I understand your opinion and I think it is all reasonable. You talk about longer compile times since every D module is like a C++ header. That touches one of my pet peeves with the language or eco system as it stands and I wonder if you would agree with me on the following:
>
> Libraries should be tied into applications using interface
> files (*.di) that are auto-generated by the compiler for the
> _library author_ with inferred function attributes. If after
> a code change, a declaration in the *.di file changes, the
> library's interface changed and a new minor version must be
> released. The language must allow to explicitly declare a
> function or method as @gc, impure, etc. so the auto-inferred
> attributes don't later become an issue when the implementation
> changes from e.g. a pure to an impure one.
> Opaque struct pointers as seen in most C APIs should also be
> considered for *.di files to reduce the number of imports for
> member fields.
>
> That means:
> * No more fuzzyness about whether a library function
>   will remain @nogc, @safe, etc. in the next update.
> * Explicit library boundaries that don't recursively import the
>   world.

I like it but I'd have to think about it a bit more.

My current idea to save me from staring at the screen for 2s at a time several times a day is to write a program using dmd as a library and integrate it into reggae that gets all of the dependencies from a given module. Then the build system reggae would generate would _not_ declare those dependencies, but actually .di files generated from them. That way a rebuild would only happen if the .di file changed, which the program would be smart enough to not overwrite if the hash/diff hasn't changed.

Atila
March 22, 2018
On Thursday, 22 March 2018 at 13:50:39 UTC, Atila Neves wrote:
> On Thursday, 22 March 2018 at 11:19:46 UTC, Basile B. wrote:
>> On Thursday, 22 March 2018 at 11:00:31 UTC, Atila Neves wrote:
>>> On Thursday, 22 March 2018 at 10:59:56 UTC, Atila Neves wrote:
>>>> Blog post:
>>>>
>>>> https://atilanevesoncode.wordpress.com/
>>>>
>>>> Atila
>>>
>>> Direct link:
>>>
>>> https://atilanevesoncode.wordpress.com/2018/03/22/keep-d-unittests-separated-from-production-code/
>>>
>>> Sorry for the forum spam.
>>>
>>> Atila
>>
>> I don't agree at all. Everything is so much faster when unittest blocks are in the same module as the stuff that are tested. Generally i think that it makes things easier.
>
> Faster as measured by what? Projects definitely take longer to build and iterate on.
>
> If you think it makes things easier, great! The blog post is my opinion.
>
> Atila

I was able to reach almost 100% coverage (99.2263) in my project Yatol just because tests are next to the code. This project has really convinced me of the fact that unittest are better in the code. This is also very good for tooling, e.g workflow in my IDE relies on tests being with the code (there's an action called Run file unittests that allows to test + cover a single module that's part of bigger project.)

I honestly think that the project i mention would be less tested if the test suite was put apart.

I don't say you are wrong, but the two or three occasional issues you mention in your blog post are really marginal things IMO, although i don't deny they are possible.
March 22, 2018
On Thursday, 22 March 2018 at 10:59:56 UTC, Atila Neves wrote:
> Blog post:
>
> https://atilanevesoncode.wordpress.com/
>

Agreed on most counts though I’d say D simply produced a language without regard for build tools and large projects. Many small annoying things like version(unittest) stem from that fact.

In addition I think many things could easily take a ton of time to compile and run tests. ctRegex is one such monster. Inadvertently pluging that into somebody else unittest build would be murder ;)

It’s a given in some other languages that you need some library support to write tests (sometimes any tests) so they usually have cleancut prod dependecies and test dependencies. Our unitest being built-in practically forces the style.

> Atila


March 22, 2018
On Thu, Mar 22, 2018 at 05:21:41PM +0000, Atila Neves via Digitalmars-d-announce wrote:
> On Thursday, 22 March 2018 at 16:30:37 UTC, H. S. Teoh wrote:
[...]
> > being tested, was a big slowdown for me.  I have to stop to think about which subdirectory under test/ I should put the relevant file(s), or if there's already a test there I have to stop to think about which filename I saved it under, etc..  It's just yet another mental hurdle to jump over while my already-busy brain is thinking about the code itself.
> 
> Then I'd recommend:
> 
> 1) To write the tests inline when the mental burden is high
> 2) Move them afterwards when one's brain can think of where to place
> them.

I don't like having to move code around after it's written.  Besides, since all sufficiently complex (i.e., sufficiently interesting) code inevitably has bugs, the set of unittests following each function is likely to keep growing, so I'd like to keep them all in one place where possible.

But at the end of the day, it really comes down to just personal preferences. The case could be equally argued both ways.


[...]
> > 2) Compilation times: perhaps if your unittests are too heavy, compilation times could become a problem,
> 
> Maybe I wasn't clear in what I wrote: I'm not saying that I notice the increase in compilation times of the tests themselves. I probably haven't but I'd have to measure to know for sure. I'm saying that if you change anything in a D module, it must be assumed that any other module that imports the module you just edited, even if transitively, must be recompiled. So if I edit a test in D, under normal circumstances, I _have_ to recompile several files. It's not the unittest itself that is heavy, it's recompiling everyone who depends on the module that said unittest happens to find itself in.

Ah, I see your point.  So the idea is to split off the unittests into a separate file that isn't among the dependencies, so that changing unittests won't force everything else to recompile.  Makes sense to me. Though I have yet to work with a project large enough where this would cause a significant degradation in compilation times.

(Having said that, though, I find the building with dub in general is extremely slow due to all the other stuff that it does besides building the code.  So if the addition of a few more modules to recompile causes a noticeable slowdown in dub, I wouldn't be surprised.)


> > but IME, they haven't been.
> 
> IME most other people find it bizarre I get angry at 2s incremental rebuild times. Anything over 100ms is an eternity.

Haha... well, then maybe you could help us reduce the compilation cost of certain common Phobos modules, like std.format. ;-)  I *love* std.format for its functionality, and use it almost everywhere in my code, but recently I've been rather disappointed at the huge slowdowns it adds to my compilation times. :-(  I wish the cost of using std.format is more proportional to how much of it I'm actually using. Currently, even something as trivial as format("%s",str) adds a significant hit to compilation times, even though conceptually it should really just be a single call to output a string.


[...]
> > As for the dub-specific problems introduced by version(unittest):
> > IMO that's a flaw in dub.
> 
> It's not dub-specific at all. It's same problem that you reference in:
> 
> > I remember that in Phobos we used to merge PRs containing code that compiles fine with -unittest, but in real-world code doesn't compile because it has stuff outside unittests that depend on imports/declarations inside version(unittest).
> 
> I used dub as an example. Anyone else would have the same problems if they hand-wrote Makefiles using git submodules as dependencies.
[...]

True.  That's why I'm inclined to say version(unittest) is an
antipattern.


T

-- 
The trouble with TCP jokes is that it's like hearing the same joke over and over.
March 22, 2018
On Thu, Mar 22, 2018 at 05:29:52PM +0000, Anton Fediushin via Digitalmars-d-announce wrote: [...]
> Oh heck yeah! I think that dub is only one of the D tools which never disappoints me.

I'm glad you found dub to your liking.  I'm afraid I can't say the same, though for reasons not really relevant to this thread.


T

-- 
If the comments and the code disagree, it's likely that *both* are wrong. -- Christopher
March 23, 2018
I think unittest blocks are good for write-once and quick-and-dirty projects, or as a first-cut of testing that ultimately gets moved to a full-grown test suite in a separate project. I'd prefer not to read source code that has unittest blocks inter-mixed with the actual code.
March 23, 2018
On Friday, 23 March 2018 at 00:47:20 UTC, Tony wrote:
> I think unittest blocks are good for write-once and quick-and-dirty projects, or as a first-cut of testing that ultimately gets moved to a full-grown test suite in a separate project. I'd prefer not to read source code that has unittest blocks inter-mixed with the actual code.

I partially agree with this.

It's really annoying if you have to look for an implementation and then half the module is unittests and searching isn't always straightforward.
March 23, 2018
On 3/22/18 6:59 AM, Atila Neves wrote:
> Blog post:
> 
> https://atilanevesoncode.wordpress.com/
> 
> Atila

It's simple. Unittests in imported modules should not be visible. They should be compiled as if -unittest was not passed.

Even Walter and Andrei are supportive: https://github.com/dlang/dmd/pull/6375#issuecomment-373487247

-Steve
March 23, 2018
On Thursday, 22 March 2018 at 15:18:40 UTC, Jacob Carlborg wrote:
> On Thursday, 22 March 2018 at 11:00:31 UTC, Atila Neves wrote:
>
>> Direct link:
>>
>> https://atilanevesoncode.wordpress.com/2018/03/22/keep-d-unittests-separated-from-production-code/
>
> I completely agree. Although my reason is mostly because there will be too much code in a single file if the regular code and unit tests are mixed in the same file.

Fully agree with this "too much code in a single file" point. I am confident that part of the reason of Phobos unittesting being very incomplete, is that adding unittests further clutters the codebase.
Moving all unittests to the bottom of the file (pulling them out of classes too) would resolve this issue in part.

- Johan

March 23, 2018
On 3/23/18 3:46 PM, Johan Engelen wrote:
> On Thursday, 22 March 2018 at 15:18:40 UTC, Jacob Carlborg wrote:
>> On Thursday, 22 March 2018 at 11:00:31 UTC, Atila Neves wrote:
>>
>>> Direct link:
>>>
>>> https://atilanevesoncode.wordpress.com/2018/03/22/keep-d-unittests-separated-from-production-code/ 
>>>
>>
>> I completely agree. Although my reason is mostly because there will be too much code in a single file if the regular code and unit tests are mixed in the same file.
> 
> Fully agree with this "too much code in a single file" point. I am confident that part of the reason of Phobos unittesting being very incomplete, is that adding unittests further clutters the codebase.
> Moving all unittests to the bottom of the file (pulling them out of classes too) would resolve this issue in part.

Note that a frequent complaint of std.datetime (at least when it was one module) is that the file was too big. While it does hold a lot of functionality, the majority of the file size is unittests. This means that it can be hard to surf the file for functionality.

But on the flip side, there aren't a lot of datetime bugs!

I personally believe that there should be unit tests for every function, and be right next to the function. I don't want to go on a search for such things, or have to rely on manual documentation to know what is testing what. It would be nice to have your editor hide the unit tests unless you want to work on them.

I've worked on a project where the testing was separated from the code, and it was a liability IMO. Things would get missed and not tested properly.

-Steve