Home Beginning D: Unit Testing, IntelliJ, & Dub
Post
Cancel

Beginning D: Unit Testing, IntelliJ, & Dub

Since my last post, I’ve done a couple things that bring my D experience more in line to a real development cycle. I’ve become more familiar with the debugging experience (with lldb), explored an IDE option (IntelliJ via plugin), and worked with the default unit testing experience.

LLDB

I’m pretty new to lldb, and my experience with gdb is very limited. I had an intro in school, and I learned a few commands from working on iOS projects, however the gui did most of the work. I’m starting to get the hang of it, and D was (un?)suprisingly easy to work with. Interrogating variables, including objects, required a little Cpp thinking but was pretty simple.

One gotcha is that static conditionals seemed to mess with the line numbers on stack traces. I can understand how this could have happened with the conditional being executed at compile time. So maybe the book keeping wasn’t properly taken care of correctly. I had to resort to print statements to figure out that “oh yeah, this branch is being executed”. This is a pretty bad gotcha. There might be a solution out there (ignorance caveat). However, I figured this out pretty quickly and setting breakpoints at each branch point still worked.

There seems to be a big different between compile time and run time comparisons especially with null (foo is null) vs (T == typeof(null). Again, I’m not very familiar with the type system, it is just an observation from creating the test suite.

Overall I found working with lldb to be easier than with either C++ or Go. And despite the inconvenience, static conditionals are such a great feature, that a little inconvenience is worth it.

IntelliJ Plugin

The D Language plugin for IntelliJ (don’t confuse it with the other similarly named one) has a solid feature set. I didn’t have any trouble setting up with the latest version of the IDE. Afterwards, the dub integration and autocompletion were very helpful.

The two glaring problems were with refactoring and debugging. Neither of these features worked at all. These are two major reasons for me to use an IDE (especially debugging). Pretty disappointing. The fast build/exec speeds of D made the lack of integrated debugging less of a pain point, but I still missed it.

Overall, definitely try out the plugin if you aren’t 100% happy with your setup, or like the other Jetbrains tools.

As an aside, Jetbrains probably makes my favorite line of IDE’s. I use vim/bash dat to day, but have found their tools very helpful when working outside of my comfortzone.

Unit Testing

Overall the default test suite is effective, if bare bones. I like the concept of collocated unit tests. And the simplicity of creating tests via built in assertions was a nice change from the test suites I’m use to with Rails and Javascript development, which require A LOT more setup.

The code coverage and unit test output was easy to understand, but rudimentary. I would like all my tests to run (even after the first failure) and give reports on each failure. And coverage would be nice if HTML output was created. These seem like tractable problems for toolmakers. If I become invested in D I will be looking at code coverage output especially.

Test Object Types

Initially I was unable to get test classes to work. A compile time error occurred saying that inner classes could not be instantiated by the inflater. Moving the definitions outside of the unittest block worked, but this is not ideal since I only wanted them to build for test, not for release. I had to declare the test classes as static classes in order for the them to work correctly.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
unittest
{
    /*
      Did not compile
    */
    class TestObj
    {
        int id;
        string name;
    }

    /*
      Worked correctly
    */
    static class TestObj
    {
        int id;
        string name;
    }
    ....
}

I’m hoping this is unique to the unittest block, and being unable to use a full namespace path for the type. Not being able to use any internal classes with timeplated functions would be a major pane.

Conclusion

I like D a lot. The language makes a lot of sense to me. I really like the compile time logic, and features based around build context like contract programming, unittests and assertions, while making it easy to strip them out for release. I like the simplicity and configurability of Dub, and I like the convenience of dfmt. I like good looking code, but I don’t want to worry about making my code look good all the time. I like the fast compile cycle, and cleaned up (relative to Cpp) syntax. However, I didn’t feel restricted, as I do sometimes with Go. And like Go I was easily able to incorporate new libraries. Adding new dependencies is integrated into dub, and exposing them to autocomplete in Vim was easy(C++ I have to reach for an IDE).

Overall my experience was positive. My language choice is very driven by practicality, but I really liked my first D experience, and I hope to many future interactions.

Lastly I should mention, I will not be publishing this library. Thanks to some helpful responders, I’ve learned there are already several other options available. And I’m not trying to republish the wheel.

-->