Creating a Go Module & Writing Tests in Less Than 3 Minutes

In this short (less than 4 minutes) video I put together a Go module library, then setup some first initial tests calling against functions in the module.

 

00:12 – Writing unit tests.

00:24 – Create the first go file.

00:40 – Creating the Go go.mod file. When creating the go.mode file, note the command is go mod init [repopath] where repopath is the actual URI to the repo. The go.mod file that is generated would look like this.

module github.com/adron/awesomeLib

go 1.13

00:56 Enabling Go mod integration for Goland IDE. This dialog has an option to turn off the proxy or go direct to repo bypassing the proxy. For more details on the Go proxy, check out goproxy.io and the Go docs for more details.

01:09Instead of TDD, first I cover a simple function implementation. Note the casing is very important in setting up a test in Go. The test function needs to be public, thus capitalized, and the function needs accessible, thus also capitalized. The function in the awesomeLib.go file, just to have a function that would return some value, looks like this.

package awesomeLib

func GetKnownResult() string {
    return "known"
}

01:30Creating the test file, awesomeLib_test.go, then creating the test. In this I also show some of the features of the Goland IDE that extracts and offers the function names of a module prefaced with Test and other naming that provides they perform a test, performance, or related testing functionality.

package awesomeLib

import "testing"

func TestGetKnownResult(t *testing.T) {
    got := GetKnownResult()
    if got != "known" {
        t.Error("Known result not received, test failed.")
    }
}

02:26Running the standard go test to execute the test. To run tests for all files within this module, such as if we’ve added multiple directories and other files, would be go test ./....

02:36Using Goland to run the tests with singular or multiple tests being executed. With Goland there are other capabilities to show test coverage, what percentage of functionality is covered by tests, and other various code metrics around testing, performance, and other telemetry.

That’s it, now the project is ready for elaboration and is setup for a TDD, BDD, or implement and test style approach to development.

For JavaScript, Go, Python, Terraform, and more infrastructure, web dev, and coding in general I stream regularly on Twitch at https://twitch.tv/adronhall, post the VOD’s to YouTube along with entirely new tech and metal content at https://youtube.com/c/ThrashingCode.

BDD Style Test Phrasing… What’s Your Poison?

I’ve had this question come up a few times recently, and I wanted to get everybody’s take on it…  when you write BDD style tests, what practice do you prefer?

…I’ll have a follow up to this poll in a few days and explain some of my own reasoning to the whole situation.

Learning “nools” Rules Engine

Recently I sat down to work up a solution around a rules engine. There were a few things I noticed right off.

  1. When there is a request to implement or build a rules engine it is very often (I’m guessing a solid 40-60% of the time) reasoned that there is a need solely based on a lack of understanding around what the problem space is that actually needs a solution. The simple assumption, is 40-60% of the time somebody says “let’s implement a rules engine to solve these unknown problems” really translates to “we really don’t know much about this domain so let’s implement something arbitrary as a stop gap”.
  2. Implementing a business rules engine can quickly become a “support the user” scenario for the developers that implement the rules engine. This is a situation in which the developers actually have to help the people writing the rules to be processed. This is not an ideal situation at all, generally developers supporting users writing rules is a quick way to ensure burn out, misappropriation of skills and turnover.
  3. Many developers will, without hesitation, spout out “are you sure you want to implement a rules engine?” and then follow that up with “let’s discuss your actual problem” with that leading to “are you sure you want to implement a rules engine?”. Other developers upon hearing that one will implement a rules engine immediately respond with, “shit, I’m out.”

At this point I realized I had X, Y and Z reason to use it and would just have to persevere with all of the threats that are inclusive of implementing a rules engine. Sometimes one just has to step into the realm of scary and get it done.

So here’s what I dug up. I’m really not sure about the name of this project, as it appears to be some sort of odd usage, so whatever, but it is indeed called nools (github repo). Nools is a business rules engine based on the Rete Algorithm, something that is helpful to read up on when implementing. The main deployment for nools is to a Node.js server, but I’ve read that it is prospectively deployable in most browsers too.
Continue reading “Learning “nools” Rules Engine”

Anti-Test Driven Development Arguments and Myths

Ok, I have run into the anti-TDD arguments on and off over the years.  Generally it comes from two primary sources.  The person who doesn’t want to do TDD no matter what, nor test, nor learn anything about the latest and greatest tech, they simply want left in their corner of the universe to code whatever they are coding until they drop dead.  Then there is the other individual who is a decent developer, but just has honest hesitations about the style.

The developer who has honest hesitations I can understand, can talk to, and can usually at least get a “Well, that sounds reasonable, but I’m still not sure” response.  Which is much better than the alternative of disregarding TDD outright.  The hope, is that this individual can at least try out TDD and see if it would work for them.

Even with the more open minded developer it is still difficult to put TDD into practice.  Why?  That’s simple, TDD is hard and forces a developer to step back into the basics and really think the problem through first.  Most developers (at least currently, maybe it’ll change) have a very “just attack the problem with code” type of response.  Often the way to break down problems is taught in computer science 101 level classes, but after that is often lost in all the cramming for math, algorithms, and other such material.  But the core fundamental idea of thinking the problem through clearly still needs to be broached.  TDD puts that idea forefront in the process by making a developer write the test to verify the problem statement first.

With all this stated, there are a few myths that I’d like to bust.  These myths are often what cause the first person to cringe away cowardly in their corner of the universe, and causes these hesitations in the second more open minded developer.  After busting these myths I’d hope more of the open minded developers can use the power and thinking that TDD encourages.  As for the first corner cringing coder, they’re a dying breed and I wouldn’t bet on their recovery.

The Myths

  • MYTH: But I can’t test every single thing that is written, so TDD just isn’t for me.  The reality is, you can’t test every single thing and you shouldn’t.  You should stick to the logic, business process, and other parts of the code.  Don’t worry about the configuration, individual database nodes, or other arbitrary or configuration based bits.  The idea is to make you think through the problem spaces and architecture needed to work through those problem spaces.  So TDD is still something you should try, but don’t try to test every single line of code.  Focus first just getting through the logical, flowing, business related bits of the code you are writing with tests first.  This will get you appropriately experienced with TDD.
  • MYTH: You can’t test against boundaries, that becomes an integration test, so why even mock/stub/fake if I’m not testing the real framework/parts/features?  Again, why worry about testing parts that you know or are not responsible for?  Don’t test the integration parts.  There is a reason QA exists, and defining and testing boundaries is what QA does great.  But you still need to test and confirm that your code works against those.  Mocking or stubbing against that gives you the confidence that your code logic will work against these integration points and also provides you a basis in which to work off of.  If you write the tests first, you also know you’ve thought through these integration points to a fairly thorough level.

Do you have anymore myths that should be burst?  Please feel free to toss a myth or two to burst in the comments, I’d love to hear others input on the matter.

Test Driven Development Built Name Generator Part 2

Part 1Part 3.

Alright, time to tear into getting that name data imported into the database.  To review the previous entry check out part 1.

Next I set the Windows App Project I added in part 1 to be the startup project.  After that I created a screen that looks like the image below (click to see larger image).

Also add an open file dialog control.  Next double click on the Process button and add the following code.  Make sure not to miss the instantiation of the names list property in the initialization.

[sourcecode language=”csharp”]
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace TextFileImporter
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Names = new List();
}

private List Names { get; set; }

private void buttonProcessFile_Click(object sender, EventArgs e)
{
if (openFile.ShowDialog() == DialogResult.OK)
{
if (File.Exists(openFile.FileName))
{
TextReader tr = new StreamReader(openFile.FileName);
textProcessedFile.Text = tr.ReadToEnd();
tr.Close();
// Cleanup text.
textProcessedFile.Text = ProcessName(textProcessedFile.Text);
}
else
{
MessageBox.Show("Select a file that exists.", "File doesn’t exist.", MessageBoxButtons.OK,
MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
}
}
}

private string ProcessName(string textBody)
{
var regex = new Regex("[^A-Z’]+");
textBody = regex.Replace(textBody, " ");

foreach (var s in textBody.Split(Convert.ToChar(" ")))
{
Names.Add(s);
}

return textBody;
}
}
}
[/sourcecode]

With the beauty of those regular expressions the files will parse appropriately in about 1-5 seconds.  Next we need a way to write this data into the database.  I did this by adding a Class Project named Generator.Core and added a folder called Model.

In the Model Directory I added a new ADO.NET Entity Framework Model.  The images below show my steps through the wizard.

  • Wizard # 1 - Adding Data Model.Wizard # 1 – Adding Data Model.
  • Wizard # 2 - Adding Data Model.Wizard # 2 – Adding Data Model.
  • Wizard # 3 - Adding Data Model.Wizard # 3 – Adding Data Model.
  • Wizard # 4 - Adding Data Model.Wizard # 4 – Adding Data Model.
  • Wizard # 5 - Adding Data Model.Wizard # 5 – Adding Data Model.

.smugcontainer div {overflow: hidden;line-height: 1.1;margin-top: 10px;font-family: verdana, arial, lucida, sans-serif;font-size: 85%;background-color1: rgb(20, 20, 20);}
.smugimg li {float: left;display: block;width: 160px;height: 200px;background-position: 50% 50%;margin-right: 10px;margin-bottom: 10px;}
.smugimg li img {width: auto; height: auto; border: solid 1px #aaa; background: #555; padding: 2px; vertical-align: middle;}
.smugimg a {display: block;text-align: center;text-decoration: none; color1: rgb(240,240,240);}
.smugimg a:hover img {border: 3px solid #6da6d1; padding: 0px;}

.smugcontainer div {overflow: hidden;line-height: 1.1;margin-top: 10px;font-family: verdana, arial, lucida, sans-serif;font-size: 85%;background-color1: rgb(20, 20, 20);}
.smugimg li {float: left;display: block;width: 160px;height: 200px;background-position: 50% 50%;margin-right: 10px;margin-bottom: 10px;}
.smugimg li img {width: auto; height: auto; border: solid 1px #aaa; background: #555; padding: 2px; vertical-align: middle;}
.smugimg a {display: block;text-align: center;text-decoration: none; color1: rgb(240,240,240);}
.smugimg a:hover img {border: 3px solid #6da6d1; padding: 0px;}

At the end I also deleted the Class1.cs file from the project.

I then added a reference to the Generator.Core Project in the TextFileImporter Application Project.  Next add an application configuration file to the TextFileImporter Project with the following configuration section.

[sourcecode language=”xml”]
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="GeneratorEntities" connectionString="metadata=res://*/Model.Data.csdl|res://*/Model.Data.ssdl|res://*/Model.Data.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=.\carriage;Initial Catalog=Generator;Integrated Security=True;Pooling=False;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
[/sourcecode]

At the last minute, and to make sure anyone following along with these instructions is really paying attention, I made a minor change to the database table.  I changed the column Type to a data type of nvarchar(50).  I then updated the Data.edmx file in the Generator.Core Project.  To do this open up the file and right click anywhere in the white space around the model.  Then click on Update Model from Database….  Now, as things go, the stupid model didn’t update for me.  This is something that seems to occur very frequetly with the ADO.NET Entity Framework Model Files.  Since it didn’t update I had to manually right click on the Type Property and then set the Type of the Type (yes I know, redundant naming) to String.

So if anyone from Microsoft is reading this, the entity model files are STILL broken for some reason.  It’s been about 6 months since the entity framework and such where in beta and they still behave in many ways like they’re in beta, please fix this.  k thx bye.

Next I double clicked the Save (buttonSaveToDb) button and entered the following code to write the file data into the database.

[sourcecode language=”csharp”]
private void buttonSaveToDb_Click(object sender, EventArgs e)
{
if (comboNameType.Text == string.Empty)
{
MessageBox.Show("Select a type of name.", "Select Name", MessageBoxButtons.OK,
MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
}
else
{
// TODO Write to DB.
var generatorEntities = new GeneratorEntities();
foreach (var name in Names)
{
var newName =
new Names
{
NameId = Guid.NewGuid(),
Name = name,
Type = comboNameType.Text
};
generatorEntities.AddToNames(newName);
}
generatorEntities.SaveChanges(true);
}
}
[/sourcecode]

Then a quick reference and that finishes up the TextFileImporter Project.

[sourcecode language=”csharp”]
using Generator.Core.Model;
[/sourcecode]

Now mind you, I broke TDD principles because this app was merely a utility, would be used a few times, and above all breaks isolation and crosses boundaries.  A good rule is to not write tests for a project like this.  Unless you feel it absolutely necessary then I wouldn’t even think of it.

Now run the application and open and import each of the three files into the database.  This will give us the data we need for the next step of our random name generator.