• A Couple Software Engineering Acronyms

    I am thinking about two acronyms: YAGNI and KISS. Really important acronyms. After picking up any technique new to me, I might want to apply it everywhere. The following thoughts serve as reminder of what is important while working through competing engineering tasks.

    YAGNI - You Aint Gonna Need It

    Keeping things decoupled is good for your codes flexibility in the future. However, don't waste time engineering, implementing, or optimizing for a future that may never come. Don't write a single line of code against a back-end you have no immediate plans to put into production. Don't force a factory pattern when you have a single implementation. Even if you have two implementations, that doesn't mandate an abstract builder.

    KISS - Keep It Simple, Stupid

    Writing clean, extensible, and robust code is important. However, solve the problems of today and when tomorrow reveals a limitation or enhancement, only then refactor. Within the constraints of test-first development, do the minimum implementation that gets the known problem solved. Another pitfall is over engineering. If adhering to a design principal means hundreds of lines of code, when you can keep testability with a dozen, you might be over engineering.


  • Nancy Is Cool

    I recently used Nancy to implement a new add-on to an existing Web Forms app. With Nancy on the backend and a some helpful front-end libs, the new implementation was quick, simple and flexible. It was a success, largely due to the development story Nancy provided.

    Web Forms, HTTP Modules, and One ASP.NET

    I initially wanted to implement with the existing code, afterall Web Forms is a powerful framework. However, its strengths and opinions are not exactly compatible with persistent single pages and asynchronous HTTP communication. This code base was one of many engineering efforts I've seen that coerce Web Forms into something that provides the feel of a single-page app . There was certainly some rough edges to work around, more importantly, I needed more control of the client pages asynchronous behavior than what was available.

    I considered implementing an ASP.NET HTTP Handler. Sounds reasonable, but I didn't want to go without model binding, URL routing, and server side HTML templates. I also didn't have the time to thrash about wiring that up. Using an existing framework would make for a quicker cleaner implementation.

    I thought about integrating ASP.NET MVC or Web API. Unfortunately, I didn't have access to the latest framework features or tooling that supports One ASP.NET. I really didn't want to spend time hacking on configuration files or trouble shooting odd inconsistencies of an ultimately unsupported development story within ASP.NET. I really needed a framework that would just allow me to execute.

    Hello Nancy

    Nancy is a small web framework that sticks close to HTTP. It allowed me to implement a robust HTTP backend with very little code. It has been built from the ground up to run anywhere. It doesn't carry the framework dependencies that Web Forms, ASP.NET MVC, or Web API share. Nor does it impose on existing ASP.NET applications. Yet, by using the Nancy.Hosting.Aspnet NuGet, I was able to quickly write the new module side-by-side with the existing code base. This even allowed me to leverage the existing application's Web Forms security context.

    Conclusion

    Each ASP.NET technology has its utility. Nancy is a great option for a variety of projects. However, here it excelled as the quickest path to delivery, while extending a long existing web application.

  • Why I Document Existing Code With Tests

    I have written my share of code without a single test, this has surely left the next guy weeping in my wake. But I have lived and learned, and now have the civility to leave behind a substantial test suite. Likewise, when I find myself being the next guy, I try not to make a change without first writing the test code.

    Before the Fix, Document With a Test

    It is a simple rule, apply TDD to the existing code. With an existing code base with little documentation and possibly vague direction, I like to identify the smallest unit test that documents the existing behavior. At a minimum it allows me to move forward with an implementation that is coupled with proof of correctness. In challenging situations it uncovers the ambiguities and ultimately leads me to the right questions. If I do (rarely) determine that some code is unreasonable to wrap in a unit test, then I usually have enough information to make a good case for a refactor, and the domain knowledge to ship a solution under test or not.

    Intended and Unintended Benefit

    I have found this approach to be incredibly useful. With it, I have uncovered bugs that would likely not have been found for some time. In that case, having the failing tests provided the basis to plan and fix the long hidden bug along with the original feature that brought me there in the first place. There are certain cases where I have skipped it, and in trivial code changes that may be fine. However, it has saved me from myself enough times to be the go to approach. As with all test-first techniques, the benefits are worth the effort.

  • Roslyn + Selenium: Scripty C# Powering Browser Automation

    Selenium makes black box style integration testing really easy. Current perception is that UI testing is brittle and generally a maintenance concern. There is an implicit cost of writing/updating, compiling, and deploying c# scripted web UI test code. However, the Roslyn project can be leveraged to stream line this process.

    As amazing as it sounds, the Roslyn project establishes the compiler as an API. I had originally heard about it on herding code 146 and immediately thought about how it could improve an existing Selenium based testing utility I had created. The fork resulted in CSharpWebScripter. For the purpose of this post the fork serves two purposes:

    • A basic demonstration on how an application can leverage the Roslyn API to compile, execute, and interact with arbitrary .csx files.
    • A simple automatable mechanism for authoring and evaluating compiler-free C# functional web tests.

    File drop deploy

    The code below is C# in a .csx file, drop it in a directory, when the exe is invoked, Selenium executes the web driver code in FireFox. When its time to add another test, drop another file, and both get executed on the next exe invocation. Maintenance against UI updates, functional changes, and bugs in test code, become a script edit and file drop.

    Making .csx feel scripty

    One goal here is to leverage existing C# language constructs, such that coding .csx feels light weight and expressive. I think this has been a goal in the evolution of C# and anticipate an emergent style around .csx coding. Here, I move as much Selenium web driver boilerplate (which isn't much) into the WebInteraction class definition. The delegate pattern is leveraged such that the bulk of the .csx script file is expressed in a lambda. Also, to futher reduce keystrokes, the class implements a fluent style method signature.

    A simple interaction with Roslyn

    With the Roslyn API a compiler and runtime can be instantiated, complete with any references required. In order to keep the .csx lighter, a few calls to ImportNamespace are made. The Execute method returns an instance of WebInteractionResult, this object is called a host object and servers as a container to transfer any data we want out of the executed .csx, and into the compiling app.

    Automating, reporting, and wrapping up

    The source also includes an NUnit test project. It leverages NUnit's TestCaseSource feature that enables n number of .csx files to be reported on as if they were a compiled test. It works well enough, however after implementing it, I am curious to see how other testing frameworks go about it.

    In conclusion, by combining Selenium, Roslyn, and NUnit, we have a simple automatable mechanism for authoring and evaluating compiler-free C# functional web tests.

  • Pane Navigation in Windows Terminals

    It's known that the Windows terminal story has lacked feature parity when compared with tools like tmux, which have long been available in Unix/Linux environments. Two projects have risen that are taking on the Windows terminal experience; ConsoleZ and ConEmu.

    I've used Console2 as my Windows terminal for sometime now, it offers tabbed views, user defined shells, and many other features. However, it doesn't offer the ability to split views and navigate between them with custom key-bindings. Standard stuff acheivable in multiple ways in Unix/Linux environments.

    ConsoleZ

    ConsoleZ is based on Console2 with some added features. Specifically, it has greatly improved the view panes and navigation experience, the following commands are key bindable.

    • New Tab
    • Next Tab
    • Previous Tab
    • Split Horizontally
    • Split Vertically
    • Switch to left View
    • Switch to right View
    • Switch to top View
    • Switch to bottom View
    • Bi-directional buffer scrolling by page, row, and column

    This does get us much of the way there. However, the following are certainly missing:

    • Pane resizing
    • Pane and Tab Shuffling

    ConEmu

    ConEmu is another project that is remarkably feature rich. However, with with respect to panes and navigation you have the following commands to bind.

    • Create new console (New Tab)
    • Duplicate active shell split to right (Split Vertically)
    • Duplicate active shell split to bottom (Split Horizontally)
    • Switch next console (Cycle panes rolling over to next tab)
    • Switch previous console (Cycle panes rolling over to previous tab)
    • Switch to next visible pane (Cycle panes on current tab only)
    • Switch to previous visible pane (Cycle Panes on current tab only)
    • Move active tab leftward (Tab Shuffling)
    • Move active tab rightward (Tab Shuffling)
    • Scroll buffer one line/page up/down (Vertical buffer scrolling)

    Unfortunately some of this behavior is not exactly intuitive, for instance you can't dart into any adjacent pane, only cycle through them. One command will jarringly skip over to the next tab and the other will not. Just as important is the lack of horizontal buffer scrolling. Again, I think we are missing:

    • Customizable tab navigation
    • True adjacent pane navigation
    • Pane Resizing
    • Pane Shuffling
    • Horizontal buffer scrolling

    It's our tools afterall

    The work done in this space is greatly appreciated. It's time to show it by providing feedback, donating, or whatever. I know I will be using these tools or iterations thereof until I keel over my box, or go into management, may as well get involved in shaping them.

OLDER