“Your request for a grant from the AST has been approved!”, Speechless. Even now as I am writing this, I don’t quite know how to describe it. Happiness? No, it had to have been something far better than that. I’ll get back to you on that one. As an entry level software tester, CAST 2016 is the top of the line if you want to learn and connect with the leading minds in the industry. It’s like telling an aspiring singer that they are going to be given the opportunity to meet their favorite artists/composers. Fast forwarding 168 hours later and 2,988 miles away from home I found myself in Vancouver where the “Lollapalooza of Software Testing” was to take place. According to the schedule my day began with “Lean Coffee”. As a frequent customer at Starbucks I knew what a skinny mocha was but “Lean Coffee” was a new one for me and I wasn’t sure what to expect. I guess you can say that from the very moment I entered Simon Fraser University I was learning new things. So what did “Lean Coffee” turn out to be? Well it was a concept I was familiar with, however this would be the first time I would be putting this into practice as part of a team. Similar to agile testing, a group of a dozen or so people gathered around a collaborative chart that organized the topics they wanted to discuss. It resembled the average person’s to-do list. One of the topics that was brought up was how folks were going to communicate after the conference and someone said something which I totally agree with which was that communication is best when it’s in person. The very idea of going to the conference was out of my comfort zone; however, I don’t regret a minute of it. It was an amazing experience!
I’d say the overall theme amongst both tutorials that I attended was that one has options. In the first lecture, Mr. Bach started by explaining the core values and meaning of testing. He then went on to talk about what we considered to be difficult to test. I brought up the idea of color and how individual perception of color can impede testing as looking for identifying factors can differ from person to person. Is it a problem? The curveball question. A war of technicality. Yes, the purpose of testing is to find problems, however, the inability to identify colors is ironically in the “grey zone”. It can be a problem but that depends on one’s interpretation. In the second lecture, Ms. Charles shaped the discussion so that the attendees took control. People were given the opportunity to seek advice from fellow testers by speaking about situations where they’ve wanted to say no. One story in particular stuck out to me which was a case of skills becoming a burden. In this story the individual found that co workers relied too much on said person’s generosity and willingness to learn things outside of the job description. The advice for this situation in particular ranged from a “don’t continue to do this” to a “speak with your superiors”.
Now let’s talk about the keynotes that took place throughout the CAST conference. Day 2 was comprised of two conferences. The opening keynote speaker was Nicholas Carr. He raised the subject about how humans have become far too dependent on automation. A plane crash is how Mr. Carr chose to illustrate his view. One small error in the pilot software can cause a pilot to go into a frenzy because the individual may not be fully capable of controlling the plane under certain stressful conditions. Conversely, his next point was about human error, “When our brain is overtaxed we find distractions more distracting”. In essence, Mr. Carr proposed a wise new division of labor that does not seek replacement but a partnership between humans and computers. The following keynote on that Tuesday was conducted by Anne Marie Charrett who presented ways to change testing environments; not the software or hardware aspect, if not the setting in which testers work. An interesting diagram was displayed during this presentation which laid out the fundamentals of this unique test management approach. The diagram seemed to consist of personality and action guidelines. The next day featured a keynote by Sallyann Freudenberg which had quite the impact with the audience. It addressed a pressing issue, employment for those with special needs in the IT field. Ms. Freudenberg started off by sharing that she found herself to be somewhere on the autistic spectrum. Perhaps the most impactful part of this keynote was when the signs and symptoms of autism were shown because it made the audience wonder about the possibility of being somewhere on the spectrum as well. It was also quite intriguing to hear about the qualities of an autistic perspective in IT, some of which included keenness for detail, a more spacial take on tasks, and the ability to complete repetitive tasks.
Prior to the CAST conference, attendees were given the choice to create a schedule for the sessions they wanted to attend. As a novice conference-goer I decided upon an impromptu approach. Choosing between these sessions was rather difficult because it was as though I had been given a menu that only offered top-notch cuisine. “What developers taught me about testing” was the session that I thought was the most appealing out of the great lineup of sessions. Ms. Charrett spoke about how to open communication with developers in a seemingly hostile environment where everyone is obsessed with their work. She taught us how create a safety net by building up trust and relationships. This made me recall a quote by A. Den Heaver that she had referenced during her keynote which said, “When a flower doesn’t bloom you fix the environment in which it grows, not the flower”.
Well, if you browse the internet regularly, you will encounter two different terms that are used rather inconsistently: Continuous Delivery and Continuous Deployment. In my words, Continuous Delivery is a collection of various techniques, principles and tools that allow you to deploy a system into production with a single press of a button. Continuous Deployment takes that to the next level by completely automating the process of putting some code changes that were committed to source control into production, all without human intervention. These concepts are not trivial to implement and involve both technological innovations as well some serious organizational changes. In most projects involving the introduction of Continuous Delivery, an entire cultural shift is needed. This requires some great communication and coaching skills. But sometimes it helps to build trust within the organization by showing the power of technology. So let me use this post to highlight some tools and techniques that I use myself.
What do you need?
As I mentioned, Continuous Delivery involves a lot more than just development effort. Nonetheless, these are a few of the practices I believe you need to be successful.
- As much of your production code as possible must be covered by automated unit tests. One of the most difficult part of that is to determine the right scope of those tests. Practicing Test Driven Development (TDD), a test-first design methodology, can really help you with this. After trying both traditional unit testing as well as TDD, I can tell you that is really hard to add maintainable and fast unit tests after you’ve written your code.
- If your system consists of multiple distributed subsystems that can only be tested after they’ve been deployed, then I would strongly recommend investing in acceptance tests. These ‘end-to-end’ tests should cover a single subsystem and use test stubs to simulate the interaction with the other systems.
- Any manual testing should be banned. Period. Obviously I realize that this isn’t always possible due to legacy reasons. So if you can’t do that for certain parts of the system, document which part and do a short analysis on what is blocking you.
- A release strategy as well as a branching strategy are crucial. Such a strategy defines the rules for shipping (pre-)releases, how to deal with hot-fixes, when to apply labels what version numbering schema to use.
- Build artifacts such as DLLs or NuGet packages should be versioned automatically without the involvement of any development effort.
- During the deployment, the administrator often has to tweak web/app.config settings such as database connections strings and other infrastructure-specific settings. This has to be automated as well, preferably by parametrizing deployment builds.
- Build processes, if they exist at all, are quite often tightly integrated with build engines like Microsoft’s Team Build or JetBrain’s Team City. But many developers forget that the build script changes almost as often as the code itself. So in my opinion, the build script itself should be part of the same branching strategy that governs the code and be independent of the build product. This allows you to commit any changes needed to the build script together with the actual feature. An extra benefit of this approach is that developers can test the build process locally.
- Nobody is more loathed by developers than DBAs. A DBA that needs to manually review and apply database schema changes is a frustrating bottleneck that makes true agile development impossible. Instead, use a technique where the system uses metadata to automatically update the database schema during the deployment.
What tools are available for this?
Within the .NET open-source community a lot of projects have emerged that have revolutionized the way we build software.
- OWIN is an open standard to build components that expose some kind of HTTP end-point and that can be hosted everywhere. WebAPI, RavenDB and ASP.NET Core MVC are all OWIN based, which means you can build NuGet packages that expose HTTP APIs and host them in IIS, a Windows Service or even a unit test without the need to open a port at all. Since you have full control of the internal HTTP pipeline you can even add code to simulate network connectivity issues or high-latency networks.
- Git is much more than a version control system. It changes the way developers work at a fundamental level. Many of the more recent tools such as those for automatic versioning and generating release notes have been made possible by Git. Git even triggered de-facto release strategies such as GitFlow and GitHubFlow that directly align with Continuous Delivery and Continuous Deployment. In addition to that, online services like GitHub and Visual Studio Team Services add concepts like Pull Requests that are crucial for scaling software development departments.
- XUnit is a parallel executing unit test framework that will help you build software that runs well in highly concurrent systems. Just try to convert existing unit tests built using more traditional test frameworks like MSTest or Nunit to Xunit. It’ll surface all kinds of concurrency issues that you normally wouldn’t detect until you run your system in production under a high load.
- Composing complex systems from small components maintained by individual teams has been proven to be a very successful approach for scaling software development. MyGet offers (mostly free) online NuGet-based services that promotes teams to build, maintain and release their own components and libraries and distribute using NuGet, all governed by their own release calendar. In my opinion, this is a crucial part of preventing a monolith.
- PSake is a PowerShell based make-inspired build system that allows you to keep your build process in your source code repository just like all your other code. Not only does this allow you to evolve your build process with new requirements and commit it together with the code changes, it also allows you to test your build in complete isolation. How cool is it to be able to test your deployment build from your local PC, isn’t it?
- So if your code and your build process can be treated as first-class citizens, why can’t we do the same to your infrastructure? You can, provided you take the time to master PowerShell DSC and/or modern infrastructure platforms like TerraForm. Does your new release require a newer version of the .NET Framework (and you’re not using .NET Core yet)? Simply commit an updated DSC script and your deployment server is re-provisioned automatically.
Where do you start?
By now, it should be clear that introducing Continuous Delivery or Deployment isn’t for the faint of heart. And I didn’t even talk about the cultural aspects and the change management skills you need to have for that. On the other hand, the .NET realm is flooded with tools, products and libraries that can help you to move in the right direction. Provided I managed to show you some of the advantages, where do you start?
- Switch to Git as your source control system. All of the above is quite possible without it, but using Git makes a lot of it a lot easier. Just try to monitor multiple branches and pull requests with Team Foundation Server based on a wildcard specification (hint: you can’t).
- Start automating your build process using PSake or something alike. As soon as you have a starting point, it’ll become much easier to add more and more of the build process and have it grow with your code-base.
- Identify all configuration and infrastructural settings that deployment engineers normally change by hand and add them to the build process as parameters that can be provided by the build engine. This is a major step in removing human errors.
- Replace any database scripts with some kind of library like Fluent Migrator or the Entity Framework that allows you to update schema through code. By doing that, you could even decide to support downgrading the schema in case a (continuous) deployment fails.
- Write so-called characterization tests around the existing code so that you have a safety net for the changes needed to facilitate continuous delivery and deployment.
- Start the refactoring efforts needed to be able to automatically test more chunks of the (monolithical) system in isolation. Also consider extracting those parts into a separate source control project to facilitate isolated development, team ownership and a custom life cycle.
- Choose a versioning and release strategy and strictly follow it. Consider automating the version number generation using something like GitVersion.
Let’s get started
Are you still building, packaging and deploying your projects manually? How much time have you lost trying to figure out what went wrong, only to find out you forgot some setting or important step along the way? If this sounds familiar, hopefully this post will help you to pick up some nice starting points. And if you still have question, don’t hesitate to contact me on twitter or by reaching out to me at TechDays 2016.
Quite OK, thanks for asking. I feel like this writing exercise helps me clear my head a bit. Many have learned by now that “all models are wrong but some are useful” – a saying attributed to the statistician George Box. In my quest for trying to understand an organization and its dynamics, I’ve come […]
Back in Part 1 I started this series of posts one Sunday morning with a very small thought on tooling. (Thinking is a tool.) I let my mind wander over the topic and found that I had opinions, knowledge, ideas, and connections that I hadn’t made ex…
In Part 1 of this series I observed my behaviour in identifying problems, choosing tools, and finding profitable ways to use them when cleaning my bathroom at home. The introspection broadened out in Part 2 to consider tool selection more generally. I speculated that, although we may see someone apparently thoughtlessly viewing every problem as a nail and hence treatable with the same hammer, that simple action can hide deeper conscious and unconscious thought processes. In Part 3 I find myself with these things in mind, reflecting on the tools I use in my day-to-day work.
One class of problems that I apply tools to involves a route to the solution being understood and a desire to get there quickly. I think of these as essentially productivity or efficiency problems and one of the tools I deploy to resolve them is a programming or scripting language.
Programming languages are are tools, for sure, but they are also tool factories. When I have some kind of task which is repetitive or tiresome, or which is substantially the same in a bunch of different cases, I’ll look for an opportunity to write a script – or fabricate a tool – which does those things for me. For instance, I frequently clone repositories from different branches of our source code using Mercurial. I could type this every time:
$ hg clone -r branch_that_I_want https://our.localrepo.com/repo_that_I_want
… and swear a lot when I forget that this is secure HTTP or mistype localrepo again. Or I could write a simple bash script, like this one, and call it hgclone:
hg clone -r $1 https://our.localrepo.com/$2
and then call it like this whenever I need to clone:
$ hgclone branch_that_I_want repo_that_I_want
Now I’m left dealing with the logic of my need but not the implementation details. This keeps me in flow (if you’re a believer in that kind of thing) or just makes me less likely to make a mistake (you’re certainly a believer in mistakes, right?) and, in the aggregrate, saves me significant time, effort and pain.
Your infrastructure will often provide hooks for what I sometimes think of as micro tools too. An example of this might be aliases and environment variables. In Linux, because that’s what I use most often, I have set things up so that:
- commands I like to run a particular way are aliased to always run that way.
- some commands I run a lot are aliased to single characters.
- some directory paths that I need to use frequently are stored as environment variables.
- I can search forwards and backwards in my bash history to reuse commands easily.
One of the reasons that I find writing (and blogging, although I don’t blog anything like as much as I write) such a productive activity is that the act of doing it – for me – provokes further thoughts and connections and questions. In this case, writing about micro tools I realise that I have another kind of helper, one that I could call a skeleton tool.
Those scripts that you return to again and again as starting points for some other piece of work, they’re probably useful because of some specific piece of functionality within them. You hack out the rest and replace them in each usage, but keep that generally useful bit. That bit is the skeleton. I have one in particular that is so useful I’ve made a copy of it with only the bits that I was reusing to make it easier to hack.
Another class of problem I bump into is more open-ended. Often I’ll have some idea of the kind of thing I’d like to be able to do because I’m chasing an issue. I may already have a tool but its shortcomings, or my shortcomings as a user, are getting in the way. I proceed here in a variety of ways, including:
- analogy: sometimes I can think of a domain where I know of an answer, as I did with folders in Thunderbird.
- background knowledge: I keep myself open for tool ideas even when I don’t need tools for a task.
- asking colleagues: because often someone has been there before me.
- research: that frustrated lament “if only I could …” is a great starting point for a search. Choosing sufficient context to make the search useful is a skill.
- reading the manual: I know, old-fashioned, but still sometimes pays off.
On one project, getting the data I needed was possible but frustratingly tiresome. I had tried to research solutions myself, had failed to get anything I was happy with, and so asked for help:
#Testers: what tools for monitoring raw HTTP? I’m using tcpdump/Wireshark and Fiddler. I got networks of servers, including proxies #testing
— James Thomas (@qahiccupps) March 26, 2016
This lead to a couple of useful, practical findings: that Fiddler will read pcap files, and that chaosreader can provide raw HTTP in a form that can be grepped. I logged these findings in another tool – our company wiki – categorised so that others stand a chance of finding them later.
Re-reading this now, I notice that in that Twitter thread I am casting the problem in terms of the solution that I am pursuing:
I would like a way to dump all HTTP out of .pcap. Wireshark cuts it up into TCP streams.
Later, I recast the problem (for myself) in a different way:
I would like something like tcpdump for HTTP.
The former presupposes that I have used tcpdump to capture raw comms and now want to inspect the HTTP contained within it, because that was the kind of solution I was already using. The latter is agnostic about the method, but uses analogy to describe the shape of the solution I’m looking for. More recently still, I have refined this further:
I would like to be able to inspect raw HTTP in real time, and simultaneously dump it to a file, and possibly modify it on the fly, and not have to configure my application to use an external proxy (because that can change its behaviour).
Having this need in mind means that when I happen across a tool like mitmproxy (as I did recently) I can associate it with the background problem I have. Looking into mitmproxy, I bumped into HTTPolice, which can be deployed alongside it and used to lint my product’s HTTP. Without the background thinking I might not have picked up on mitmproxy when it floated past me; without picking up on mitmproxy I would not have found HTTPolice or, at least, not found it so interesting at that time.
Changing to a new tool can give you possibilities that you didn’t know were there before. Or expose a part of the space of possible solutions that you hadn’t considered, or change your perspective so that you see the problem differently and a different class of solutions becomes available.
Sometimes the problem is that you know of multiple tools that you could start a task in, but you’re unsure of the extent of the task, or the time that you’ll need to spend on it, whether you’ll need to work and rework or this is a one-shot effort and other meta problems of the problem itself. I wondered about this a while ago on Twitter:
With experience I become more interested in – where other constraints permit – setting up tooling to facilitate work before starting work.
— James Thomas (@qahiccupps) December 5, 2015
And where that’s not possible (e.g. JFDI) doing in a way that I hope will be conducive to later retrospective tooling.
— James Thomas (@qahiccupps) December 5, 2015
And I mean “tooling” in a very generic sense. Not just programming.
— James Thomas (@qahiccupps) December 5, 2015
And when I say “where other constraints permit” I include contextual factors, project expectations, mission, length etc not just budget
— James Thomas (@qahiccupps) December 5, 2015
Gah. I should’ve started this at https://t.co/DWcsnKiSfS. Perhaps tomorrow.
— James Thomas (@qahiccupps) December 5, 2015
I wonder if this is irony.
— James Thomas (@qahiccupps) December 5, 2015
A common scenario for me at a small scale is, when gathering data, whether I should start in text file, or Excel, or an Excel table. Within Excel, these days, I usually expect to switch to tables as soon as it becomes apparent I’m doing something more than inspecting data.
Most of my writing starts as plain text. Blog posts usually start in Notepad++ because I like the ease of editing in a real editor, because I save drafts to disk, because I work offline. (I’m writing this in Notepad++ now, offline because the internet connection where I am is flaky.) Evil Tester wrote about his workflow for blogging and his reasons for using offline editors too.
When writing in text files I also have heuristics about switching to a richer format. For instance, if I find that I’m using a set of multiply-indented bullets that are essentially representing two-dimensional data it’s a sign that the data I am describing is richer than the format I’m using. I might switch to tabulated formatting in the document (if the data is small and likely to remain that way), I might switch to wiki table markup (if the document is destined for the wiki), or I might switch to a different tool altogether (either just for the data or for everything.)
At the command line I’ll often start in shell, then move to bash script, then move to a more sophisticated scripting language. If I think I might later add what I’m writing to a test suite I might make a different set of decisions to writing a one-off script. If I know I’m searching for repro steps I’ll generally work in a shell script, recording various attempts as I go and commenting them out each time so that I can easily see what I did that lead to what. But if I think I’m going to be doing a lot of exploration in an area I have little idea about I might be more interactive but use script to log my attempts.
At a larger scale, I will try to think through workflows for data in the project: what will we collect, how will we want to analyse it, who will want to receive it, how will they want to use it? Data includes reports: who are we reporting to, how would they like to receive reports, who else might be interested? I have a set of defaults here: use existing tooling, use existing conventions, be open about everything.
Migration between tools is also interesting to me, not least because it’s not always a conscious decision. I find I’ve begun to use Notepad++ more on Windows whereas for years I was an Emacs user on that platform. In part this is because my colleagues began to move that way and I wanted to be conversant in the same kinds of tools as them in order to share knowledge and experience. On the Linux command line I’ll still use Emacs as my starting point, although I’ve begun to teach myself vi over the last two or three years. I don’t want to become dependent on a tool to the point where I can’t work in common, if spartan, environments. Using different tools for the same task has the added benefit of opening my mind to different possibilities and seeing how different concepts repeat across tools, and what doesn’t, or what differs.
But some migrations take much longer, or never complete at all: I used to use find and grep together to identify files with certain characteristics and search them. Now I often use ack. But I’ll continue to use find when I want to run a command on the results of the search, because I find its -exec option a more convenient tool than the standalone xargs.
Similarly I used to use grep and sed to search and filter JSON files. Now I often use jq when I need to filter cleanly, but I’ll continue with grep as a kind of gross “landscaping” tool, because I find that the syntax is easier to remember even if the output is frequently dirtier.
On the other hand, there are sometimes tools that change the game instantly, In the past I used Emacs as a way to provide multiple command lines inside a single connection to a Linux server. (Aside: putty is the tool I use to connect to Linux servers from Windows.) When I discovered screen I immediately ditched the Emacs approach. Screen gives me something that Emacs could not: persistence across sessions. That single attribute is enough for me to swap tools. I didn’t even know that kind of persistence was possible until I happened to be moaning about it to one of our Ops team. Why didn’t I look for a solution to a problem that was causing me pain?
I don’t know the answer to that.
I do know about Remote Desktop so I could have made an analogy and begun to look for the possibility of command line session persistence. I suspect that I just never considered it to be a possibility. I should know better. I am not omniscient. (No, really.) I don’t have to imagine a solution in order to find one. I just have to know that I perceive a problem.
That’s a lesson that, even now, I learn over and over. And here’s another: even if there’s not a full solution to my problem there may be partial solutions that are improvements on the situation I have.
In Part 1, I described my Sunday morning Cleaning the Bathroom problem and how I think about the tools I’m using, the way I use them, and why. In particular I talked about using a credit card as a scraper for the grotty build up around the s…
It’s early on a Sunday morning and I’m thinking about tools. Yes, that’s right: Sunday morning; early; tools.Sunday morning is bathroom cleaning morning for me1 and, alongside all the scrubbing, squirting, and sluicing I spend time evaluating the way I…
TL;DR This post is follow up on my post about traveling to CAST 2016 as software tester. In that post I mentioned that I noticed at Paris Charles De Gaulle Airport metal pattern at the top of the stairs. Using Google, I tried to find out the purpose of that pattern, but with no result. … Continue reading Stairs help for blind people →
Last night I attended a software testing meet-up where Örjan spoke about his experiences in Managing Quality in an Agile team. He raised a few interesting points from a management perspective – but it was one in particular that caught my attention: protecting time.
In order to help his team achieve the tasks they planned in sprints, he would try and stop people hindering his team unnecessarily. He wanted to help make it easier for his team to work. And I get that. I’ve been on both sides of the equation – I’ve been the person trying to ask a developer questions only to be blocked by their dev team lead and I’ve also been the person who’s been “protected” by their team lead so I can focus on my work and reach a deadline. From both perspectives I’ve been able to appreciate both the frustrations and the benefits of such an approach.
But what interests me – is the different ways people go about protecting their time.
Blocking off certain periods of times for meetings
At a recent project, they protected their time by blocking off meetings on Tuesdays and Thursdays. If you wanted to have a meeting on one of those days, it’d just have to wait until the following Wednesday and Friday (this has been going on for almost a year now)
A guy in the meet-up said that his team tried to block off meetings in the afternoons and asked for advice from the meet-up group on how to go about achieving that, as that approach only worked for a few months. A few people encouraged him to get “buy-in” from different members of the team. In retrospect, I wish I asked him a few more questions about his situation instead of just giving him my thoughts on the matter. Lesson learned.
Designated question person
Two people in the meet-up had a similar approach to protect their time and that was to have a designated question person who would answer questions/deal with issues from people outside of the team. The role would rotate on a regular basis (whether that be daily or weekly).
They also elaborated on the benefits of this role – other than having less people being interrupted, it meant that the designated person probably knew when was the best time to ask questions etc. from a member of their own team (to minimise the risk of disrupting their flow).
The identity of this person would be communicated to other teams affected, for example – through a sign that says “Support” on their desk.
Do not Disturb
Make meetings less appealing
Black Box, White Box, Gray box throw those words away. Test the thing not the box it came in… That little gem came straight from Janet Gregory during the Testers Role in Agile Requirements Exploration Workshop at CAST 2016. I struggled with choosing what sessions to attend, I didn’t want to miss anything and this … [Read more…]