Saturday, December 24, 2016

2016 in Review

I’ve heard a lot of complaints about 2016 in general, but for me it was an abundant year. Personally I enjoyed a challenge I gave myself to speak more often than 2015, and believe I succeeded by giving well over one dozen talks on topics ranging from Angular 2 and TypeScript to DevOps.

This year I became a Samsung fan. I traded in my Windows Phone for a Samsung Galaxy 7. I also purchased the Oculus-powered Gear VR and have enjoyed it more than I imagined. I still spend time in VR every week and find the immersive experience far more rewarding than the augmented reality of the HoloLens.

I ditched my Microsoft Band 2 after having to replace it under warranty for the third time. I waited patiently and picked up a Samsung Gear S3.

gears3-1

After a lot of research I decided I didn’t need a hardcore fitness band, but preferred a smartwatch that had great fitness features. The Gear S3 looks sharp:

gears3-2

It has a great battery life (over a day so I can always find time to charge), recharges wireless and fast, and has great functionality. For example, you’d think setting reminders using just your voice or answering the phone through the microphone and speaker in your watch are novelty items, but I’ve done both in practice and it’s helped me out in situations when I didn’t want to pull my phone from my pocket.

gears3-3

The fitness features are phenomenal. It has great detection for steps and flights of stairs, very accurate heart rate (I know because I monitor mine manually quite frequently), auto-detects exercise, and has a running mode that makes it easy to see your lap time, stride, and other stats “on the run.”

Trust me, I didn’t receive any of these items as promotional gear and was surprised to find myself getting so many Samsung products. The most fun I had was with my Gear 360. This boasts two fish-eye lenses with slightly more than 180 degrees of view, so it can simultaneously capture all directions and digitally glue the seams. I purchased it to capture the summits of mountains we climbed over the summer, like our first 14,000 foot tall peak (click the images to scroll in 360 degrees):

…and the grueling half marathon hike up Pike’s Peak:

In general I was not surprised to see our project work pick up momentum with Angular 2. I was surprised to see the strides we made with Agile and adoption of DevOps. We were able to automate deployment for several large customers and closed out the year with a strong focus on containers (Docker), mobile (with both Ionic and Xamarin), and mobile DevOps.

The Year of the Blog

This blog should get a new name because I haven’t posted nearly as much content related to C#. Most of my focus has been on front-end, JavaScript and TypeScript development, with a lot of Angular 2, as well as Agile and DevOps concerns. Total sessions and page views are down from last year, but I’m not surprised because I did not post nearly as frequently. Instead, I presented dozens of talks, published several articles, and focused heavily on building the app dev practice at iVision.

2016blog

Top referrals to my personal blog were from Twitter, Stackoverflow, a previous company I worked for and the DZone.

Demographics remain similar, with a dominantly young, male audience, the majority from the U.S. followed by India, the United Kingdom, Germany, and Russia.

Chrome continues to dominate the browsers that visit my site, edging up to 73% from last year’s 67%. Firefox holds second place at 11% and Internet Explorer holds a close tie with Safari at just around 5% each.

Despite publishing several dozen posts this year, older articles still remain the most viewed. The top three were:

  1. The Top 5 Mistakes AngularJS Developers Make (but when I give Angular talks, it seems like people are still making them)
  2. Model-View-ViewModel (MVVM) Explained (that is a 6 year old article – also translated to Spanish!)
  3. Windows 8 Icons (huh?!)

A goal of mine for 2017 is to be more consistent with this blog and balance my writing between work, this blog, and the various sites I freelance for.

The Year in GitHub

Last year I became really active with GitHub. I’m finally used to and comfortable with git and do so much work with Node.js and other open source projects it was just a logical transition.

2016github

I closed out the previous year explaining how dependency injection works with the jsInject project (I plan to package that for npm soon); rewrote my Angular 1.x Health App in Angular 2, ECMAScript 2015, and with Redux and Kendo UI;  ported my 6502 emulator to Angular 2 with TypeScript; wrote a text-based adventure game; created a full day Angular 2 and TypeScript workshop; and recently published a simple microservices locator.

I’m looking forward to many more open source projects in 2017!

The Year in Twitter

This year was interesting on Twitter. I continued to gain steady followers but it was much more “two steps forward, one-and-a-half steps back” than previous years. I’m not sure if it’s due to the breadth of topics, typical attrition, or some other factor, but it has been slower growth.

jeremytwitter

To date, all of my Twitter growth has been organic. I haven’t applied to any “gain x followers” and do not follow others for a follow back. I try to keep the list of those I follow at just under 1,000 and prune the list based on signal-to-noise ratio, people I genuinely know and people with topics or feeds that I am passionate about.

Most Viewed

With no competition, Angular 2 was the topic on Twitter this year. All top views are related (even RxJS is popular due to its inclusion in the Angular 2 distribution).

Most Liked

The most liked followed the most viewed closely with the exception of:

Most Clicked

The top clicked tweets align with the top viewed and liked. The fifth most popular was this critique of Angular 2 which many told me "wasn't fair" but I like to post contrasting articles for balance in my feed:

2017 Predictions

What do I predict for 2017?

Personally, I will continue to speak as often as I can. I love reaching the developer community and all of my talks are based on real world experience. I’ve found it helps to connect when you are able to relate technology in terms of “lessons learned” and case studies “in the real world.”

I hope to continue to grow my knowledge in the DevOps space and believe we will see an exponential increase of containerized (Docker-based) workloads in 2017. With the introduction of .NET Core and SQL Server on Linux, we’re also going to see many organizations shift from traditional Windows-based infrastructure to commodity Linux machines running as VM and Docker hosts. Finally I do believe in 2017 the “native vs. hybrid” debate will fade and it will truly become, “What is your development tool of choice?” as options like NativeScript and Xamarin enable developers to write native mobile apps using the language and development environments of their choice.

My last prediction? I think I’ll be using a lot of Visual Studio Code next year.

I wish you a very Merry Christmas and Happy New Year.

Until next time,

Thursday, December 8, 2016

Integrating Angular 2 Unit Tests with Visual Studio Team Services

DevOps focuses on continuous delivery of value by removing barriers between application development and operations teams. A crucial component of the DevOps pipeline is continuous integration (CI). CI is the process of automating a build and tests to ensure a stable code branch. Traditionally this has been difficult to achieve in web-centric and Single Page Applications (SPA) that focus on the front-end, but modern libraries and tools make it a lot easier to “chase the unicorns.”

junitvsts

I recently published an application to GitHub that features Angular 2, Redux, and Kendo UI. It also continuously integrates and deploys to a Docker host. You can view the running app here. It is run as a Docker container, managed by a Docker host, on an Ubuntu (Linux) server hosted in Azure.

Although the source is hosted on GitHub, I connected the repository to Visual Studio Team Services (VSTS) for continuous integration and deployment. The app has over sixty (60) automated tests that are run as part of integration. It is critical to ensure that all tests pass before the Docker image is created and deployed to production. It is also important to see the detailed results of tests so that broken builds can be quickly triaged and addressed.

Good Karma

I used the Angular Command Line Interface to scaffold the project. Out of the box, the Angular-CLI leverages Jasmine to define tests and Karma to as its test-running suite. A Jasmine test might be a simple unit test based on pure JavaScript:

Angular 2 provides a test service that enables integration-style tests that interact with actual web components:

Either way, the tests “as configured” aren’t good enough for an automated build via VSTS for two reasons:

1. They depend on a browser to host the tests (Chrome, by default) that isn’t available on the build server.

2. They only generate output to the console and don’t create a file that can be parsed for test results.

The Phantom Browser

The first step is to get rid of the browser dependency. Fortunately, a project was created to provide a “headless browser” or one that runs without rendering “real” UI, and it is called PhantomJS. To include it in my project, I issued the following command:

npm i phantomjs-prebuilt --save-dev

This creates a development dependency on the pre-built version of PhantomJS so that the project can pull it down and install it as a dependency. It adds the reference to the project’s package.json file.

The next step is to add a launcher to Karma. These packages help link Karma to browsers so Karma is able to launch the host to run the tests. The Karma launcher is installed like this:

npm i karma-phantomjs-launcher --save-dev

Finally, you need to edit the karma.conf.js configuration file to include the launcher:

Now you verify the setup by running the tests through PhantomJS:

ng test --browsers=PhantomJS

You should see the same output you normally see from Chrome, with the exception that no external browser is launched.

Note: some build machines may require you to install additional prerequisites for PhantomJS. For example, Ubuntu requires additional font libraries to be installed.

JUnit of Measure

The next requirement is to generate output that can be parsed by the build. Karma uses reporters to provide test results, and ships with a “progress” reporter that writes test results out to the command line.

testrun

By default, VSTS is able to process JavaScript unit tests in the JUnit format. Karma has a JUnit reporter that can be installed:

npm i karma-junit-reporter --save-dev

This can be added to the Karma config file the same way the PhantomJS launcher was. Now you can run tests using the --reporters=junit flag and the test run will generate a file named TESTS-browser_(platform).xml. For example, a local run on Windows 10 creates TESTS-Chrome_54.0.2840_(Windows_10_0.0.0).xml. If you open the file, you’ll see XML that defines the various test cases, how long they ran, and even a structure that holds the console output.

Configuring VSTS

I assume you know how to configure builds in VSTS. If not, check out the full CI/CD article. The build steps I created look like this:

buildsteps

The first step ensures the Angular Command Line interface is installed on the environment. The package manager command is install and the arguments are:

-g [email protected]

(This is the version the project was built with). The second step installs the dependencies for the project itself and just uses the install command with no arguments.

With the Angular-CLI installed, we can now run a command to execute the tests and generate the output file. I use two reporters. The progress reporter allows me to see the progress of the test run in the console output for the build and will abort the build if any tests fail. The JUnit reporter writes the test results file. The tool is ng and the arguments:

test --watch=false --single-run=true --reporters=junit,progress --browsers=PhantomJS

The next step instructs the VSTS agent to read the test results file and integrate it into the build results. This is what the configuration looks like:

publishtest

Here is a snippet of the test run output:

testrunoutput

That’s it! Now the automated build can create the Angular 2 production application after verifying tests successfully ran. The VSTS build log will contain specific test results and even allow you to set up a widget to chart pass/fail percentage over time. Release Management can then take the results of a successful build and deploy to production. For a more comprehensive overview of the CI/CD process, please read DevOps: Continuous Deployment with Visual Studio Team Services and Docker.

Happy DevOps!

Saturday, July 30, 2016

An Adventure in Redux: Building redux-adventure

Redux is a “predictable state container for JavaScript apps.” If you’re like me, reading about a new technology is nice but it takes a good project to really understand it. For some reason, when I hear “state machine” I immediately think of the Z-machine that was created “on a coffee table in Pittsburgh in 1979” that revolutionized computer games in the early 80s by bringing text-based adventure games to myriad platforms.

thumbnail

I originally thought of re-factoring my 6502 emulator to use Redux, but realized it would be a far bigger task to take on so I decided to build something from scratch instead. Borrowing from an app I wrote for a book I published a few years ago, I built redux-adventure using Angular 2 and TypeScript with the Angular-CLI.

Redux Concepts

There are numerous tutorials online that cover Redux. One problem I find is that a lot tend to overcomplicate the description and throw graphs that make it look far more involved than it really is. Rather than re-inventing the wheel, I’ll share a simple description here and then walk through the app that uses it.

Redux is a simple state management tool. Your application may transition through multiple states. At any given time you may raise an event, or create an action, that results in a new state. State is immutable, so actions will never modify the existing model that represents your state but instead will generate a new model. This is the concept that is sometimes difficult to understand.

Redux keeps track of state for you, and offers three key services (there are other APIs, but I’m keeping this simple).

  • The ability to dispatch an action, indicating a transition in state
  • A set of reducers that respond to an action by providing the new state
  • A subscription that receives a notification any time the state changes

The game

The redux-adventure game is fairly straightforward. You are dropped in a random room in a dungeon and must explore the dungeon to find various artifacts. You can look or travel in the four compass directions, and if there is an item you can get it to put it into your inventory. You win the game by retrieving all of the available items.

State

The state itself is really just a domain model represented by a plain-old JavaScript object (POJO). A “thing” or artifact has a name and a description. Then there are rooms that look like this:

Notice that a room may contain more than one inventory item. It also keeps track of other rooms based on compass direction and walls where there are no rooms to navigate to.

The world itself is represented by a dungeon class that contains rooms, the player’s inventory, the count of total items they must obtain, the current room, a console that contains the text displayed to the user, and a flag indicating whether or not the player has won.

There is also a dungeonMaster that generates the world from some seed information and randomly generates walls. Any classes or services with behavior have their own tests. Now that we have the world defined, what can we do?

Actions

The user can type in any number of commands that are represented by the action list. Although an action may start as these commands, based on the current state they end up being translated into four key actions:

  • Move: updates the current room to the room the user has navigated to, and updates the console to indicate the movement and display the description of the new room
  • Get: transfers inventory from the current room to the user
  • Text: adds a line of text to the console
  • Won: transfers the final item of inventory to the user, sets the won flag, and updates the console to indicate the user has won

The createAction method is responsible for this logic. TypeScript allows me to write interfaces to make it more clear what an action inspects. Here is the “get” action’s interface:

And here is the code that takes the original action and transforms it into an internal one:

Notice that one “incoming” action can translate to three “internal” actions: text with a snarky comment when there is nothing to get, an action to transfer the inventory to the user, and an action to indicate the user has won.

The translation of actions is fully testable. Note that to this point we’ve been working in pure TypeScript/JavaScript – none of this code depends on any external framework yet.

Reducers

Reducers may take awhile to get used to, but in essence they simply return a new state based on an action and ensure the existing state isn’t mutated. The easiest way to tackle reducers is from the “bottom up” meaning take the lower level properties or nested objects and handle their state, then compose them into higher levels.

As an example, a room contains a set of inventory items. The “get” action transfers inventory to the user, so the things property of the room is updated with a new array that no longer contains the item. Here is the TypeScript code:

If the ellipses notation is confusing, it’s part of a newer spec that allows for composition of items. It essentially represents a portion of the array. What is returned is a new array that no longer has the item. Here is the JavaScript:

You can view the corresponding tests written in TypeScript here. Notice that in the tests, I use Object.freeze to ensure that the original instances are not mutated. I freeze both the individual items and the list, and then test that the item is successfully removed.

Another reducer will operate on the array of inventory items for the player. Instead of removing the item as it does from the room, it will return a new array that adds the item to the player’s inventory.

The reducer for the room calls the reducer for the things property and returns a new room with properties copied over (and, in the case of navigating to the room, sets the visited flag).

You can view the main reducer code to see the logic of handling various actions, and calling other reducers as well (i.e. main calls the reducer for the rooms list, and rooms calls the reducer for the individual room).

In the end, the tests simply validate that the state changes appropriately based on an action and doesn’t mutate the existing state.

At this stage the entire game logic is complete – all state transitions through to a win are there, and we could write some simple AI to have a robot play the game and output its results. Everything is testable and we have no dependencies on any frameworks (including Redux) yet.

This is a powerful way to build software, because now whether you decide to use Angular, React, plain JavaScript or any other framework, the main business logic and domain remains the same. The code doesn’t change, the tests are all valid and framework agnostic, and the only decision is how you render it.

The Redux Store

The purpose of Redux is to maintain the state in a store that handles the actions and applies the reducers. We’ve already done all of the legwork, all that’s left is to create the store, respond to changes in state, and dispatch actions as they occur.

The root component of the Angular application handles all of this:

Notice how simple the component is! It doesn’t have to handle any business logic. It just creates the store, refreshes a property when the state changes, and dispatches actions.

The template is simple as well. It lists the console, provides a parser to receive user input if the game hasn’t been won yet, and renders a map of the rooms.

With this approach, the components themselves have no business logic at all, but simply respond to the bound data. Let’s dig a little deeper to see.

Components

Approaching the application in this fashion makes it very easy to build components. For example, this is the console component. It does just two things: exposes a list of text, and responds to changes by setting properties on the div element so that it always scrolls the latest information into view:

If you’re nervous about seeing HTML elements mixed in with the component, don’t worry! They are completely testable without the browser:

The parser component solely exists to take input and dispatch actions. The main component listens to the parser and uses the event emitter to dispatch actions to the Redux store (that code was listed earlier). The parser itself has an action to emit the input, and another action that auto-submits when the user hits ENTER from within the input box:

After playing the game I realized it would be a lot easier to test if I had a map, so I created the map component to render the grid and track progress. The map component itself simply translates the list of rooms into a matrix for rendering cells. For each cell, a green square indicates where the user is, a white square is a visited cell (with walls indicated) and a black cell is a place on the map that hasn't been explored yet.

Despite the heavy manipulation of styles to indicate background colors and walls, this component is also completely testable without relying on the browser.

Conclusion

You can view the full source code on GitHub and play the game here. Overall, building this was a great learning experience for me. Many of the articles I read had me slightly confused and left me with the feeling it was overcomplicating things, but having gone through the process I can clearly see the benefits of leveraging Redux for apps.

In general, it enables me to build a domain using vanilla TypeScript/JavaScript and declare any logic necessary on the client in a consistent way by addressing actions and reducers. These are all completely testable, so I was able to design and validate the game logic without relying on any third party framework.

Linking Redux was an easy step, and it made the logic for my components even easier. Instead of encapsulating services to drive the application, I was able to create a store, respond to changes to state within the store, and build every component as a completely testable, independent unit.

What do you think? Are you using Redux in your apps? If you are, please use the comments below to share your thoughts.