May 02, 2016

main is just another function

Last week I talked about code that isn’t unit-testable, at least not by my definition of what a unit test is. In keeping with that, this blog post will talk about testing code that has side-effects.

Recently I’d come to accept a defeatist attitude where I couldn’t think of any other way to test that passing certain command-line options to a console binary had a certain effect. I mean, the whole point is to test that running the app differently will have different consequences. As a result I ended up only ever doing end-to-end testing. And… that’s simply not where I want to be.

Then it dawned on me: main is just another function. Granted, it has a special status that makes it so you can’t call it directly from a test, but nearly all my main functions lately have looked like this:

int main(string[] args) {
    try {
        doStuff(args);
        return 0;
    } catch(Exception ex) {
        stderr.writeln(ex.msg);
        return 1;
    }
}

It should be easy enough to translate this to the equivalent C++ in your head. With main so conveniently delegating to a function that does real work, I can now easily write integration tests. After all, is there really any difference between:

doStuff(["myapp", "--option", "arg1", "arg2"]);
// assert stuff happened

And (in, say, a shell script):

./myapp --option arg1 arg2
# assert stuff happened

I’d say no. This way I have one end-to-end test for sanity’s sake, and everything else being tested from the same binary by calling the “real” main function directly.

If your main doesn’t look like the one above, and you happen to be writing C or C++, there’s another technique: use the preprocessor to rename main to something else and call it from your integration/component test. And then, as they say, Bob’s your uncle.

Happy testing!


April 30, 2016

Worth Reading (March+April 2016)

The following stuff is what caught my eye in the last couple of weeks. Consider these kind of posts as an entry in my personal knowledge base ;)

Tools: oh my zsh

Great tool to have a an extendended and improved feature set on the shell in osx: zsh with iterm. I use them both now for months successfully and do not want to miss them, it looks better and is a lot more powerful:

zsh

setup zsh on osx

GDC: “Story of making Diablo” by David Brevik

An awesome background story about the creation of one of my alltime fave games Diable by Blizzard. Learn how it at first was supposed to be a round based RPG:

gamasutra

Post: “From Browser to Mobile Game Development – An InnoGames Retrospective” by Dennis Rohlfing

My colleague and friend Dennis Rohlfing wrote a insightful article how our employer - a traditional browser games company - made the transition to mobile:

article on gamasutra

Podcast: JS Jabber with Marcus Blankenship on “Growing Happy Developers”

I really enjoyed this podcast about how to make your employee developers happy, how to be a good boss. I think a lot more focus should be put into discussing these topics, because there is nothing more important than being a boss that your developers like to work with:

podcast on js jabber

Podcsat: SE Radio with Fred George on “Developer Anarchy”

Fred George has the opportunity to be working in a field where your software product can be deployed in a fast paced manner and get feedback equally rapid (online advertising). In this podcast he talks about what changes this brings to the agile process and how well a managerless approach works here. He agrassively calls it “developer anarchy”. Unfortunately this does not fit all:

podcst on se radio

Tweet: Ebay starts looking into D

Finally another big company starts to play around with D and it is nothing less than ebay:

Post: “PGO: Optimizing D’s virtual function calls”

Read about LDC the LLVM based D compiler does optimize virtual function calls now:

PGO for D

Dconf 2016

Finally the soon to be held dconf schedule is out and it is going to be awesome:

Dconf 2016 Schedule

I am especially excited to hear about Remedys usage of D in their latest AAA game Quantum Break by Ethan Watson: “Quantum Break: AAA Gaming With Some D Code” link to talk

April 23, 2016

DerelictPHYSFS 2.0.0

DerelictPHYSFS spent quite some time languishing at the bottom of the second page of DerelictOrg projects, starving for attention. I created it on a whim a couple years ago when I wanted to use PhysicsFS for a project that I subsequently abandoned. In the time since, there have been no PRs for the project, no emails asking for help, no enhancement requests, nothing. So there it sat, forgotten.

Recently, I’ve begun work on assembling a codebase from the numerous abandoned games and graphics projects scattered around my dev projects folder. That eventually led me back to DerelictPHYSFS and a simple wrapper I had made for it (see Defile). The README for DerelictPHYSFS was still pointing to the old, defunct documentation page on this blog, rather than to the pages at derelictorg.github.io (which are still far from complete, but should currently be informative enough to use any Derelict package without much difficulty). The binding itself was stable. The 2.0.x API of PhysicsFS had not changed since I first made the binding (the last stable release, 2.0.3, was in October, 2012!), but the 2.1 API is what you get when building PhysicsFS from the development branch.

I normally don’t like to update Derelict bindings against unreleased versions of a C library, but in this case I think an exception is warranted. Any shared libraries built from the development branch of PhysFS would be compatible with the existing binding, but it would be nice to be able to make use of the newer API. So I’ve updated DerelictPHYSFS to the unreleased PhysicsFS 2.1. You can get that in the 2.1 branch on github, or through a dependency version of ~>2.0.0 in your dub configurations. The original binding is still there in the 2.0 branch, currently at version 1.0.3 as a dub dependency. I have no plans to update it further, unless someone is using it and really needs a bugfix (but I don’t think many people actually are using it).

I’ve also updated Defile to depend on the new version of DerelictPHYSFS. I intend to expand its API as I need it. It’s been available in the dub registry for quite some time and is still there for anyone who wants to use it. If you do, I make no promises about support. It’s a personal project that I decided to share with others and not something I intend to make room in my schedule to support for anyone other than me. Simple bug fixes or enhancements, maybe (definitely those that benefit me!), but anything time consuming? Forget it. Don’t let that discourage you from using it, though, if it’s something you need. It’s Boost licensed, so feel free to take it and do what you want with it.

There’s a lot of work I intend to get done with Derelict in the coming months. I need to update DerelictAllegro5 to Allegro 5.2 and get it into what I consider the right state for a 1.0.0 tag. I need to add support to DerelictLUA for Lua 5.1 so it can be used with LuaJIT. I also want to implement a static binding configuration for it like I did for DerelictGLFW3. I intend to do the same for a few other Derelict packages. I also need to work more on the documentation. That’s all competing with my plans for learningd.org and the example project from the book, the game-oriented stuff I’ve been working on the past few weeks, and some writing projects (not related to D or anything tech) I’ve got underway. Anyone got any spare time for sale?