Monthly Archives: April 2016

How do you learn to program?

Following on from my last post, you might’ve decided you want to learn how to program, but now you need to work out how. First off let me make a confession, I am a massive Python fanboy, it’s got the ease of reading, the speed of writing and you can get some deep C hooks and exploit some speed that you might not think you could from an interpreted language. Yes it has its cons, not everyone likes duck typing, significant whitespacing or the fact that if you’re using Python for threads, you’re going to have a bad time (I/O threads excluded). Still despite its drawbacks, I’ve never used any programming language as quick and enjoyable to write.

So I’ll come right out and say it; if there’s a choice, use Python. You might not have a choice, your automation framework might be Java, Ruby, Javascript or even C or C++, without stepping into .Net shops where C# might rule the roost. You’ve got to learn a language that you can use regularly or you’ll learn slowly.

So that, right there, gives us our first method for learning to program, write programs. Sounds simple, but is harder than you think. You can follow along with any number of lessons from the internet that tell you how to write programs, you can do that and sure, you’ll learn the content no doubt. But if you want to learn it faster? You do the very basic lessons and then you start to write programs that matter to you.

Secondly, care about it. This is a very hard one to envisage yourself ever doing, but much easier to actually do. Get into your programs, when you learn something new you should stop for a moment and take pride in it. Every new method you learn to solve a programming problem is another tool in your tool box. When all you have is a hammer, everything looks like a nail. When you’ve got a properly filled toolbox, you can do a lot more.

Thirdly, learn to love failure. A lot’s been written on this subject, but programming always takes place on the very edge of your competence. If you know how a problem should be solved, it’s just rote work to get the job done and you’ll find your attention slipping, mine does. But when you’re faced with something you don’t understand how to do, that’s when it gets interesting. Suddenly you’re forced to learn again, learn more. And what you learn, sticks, because you take pride in your solution to a new challenge. You will fail. You will fail over and over. At first you’ll be failing at the small things, punctuation, capitalisation. Later on you’ll be failing because you’re reading from random memory or not checking your inputs for buffer overflows.

You might enjoy the early failing more. But if you accept it’s going to happen, you’ll enjoy all of it as a learning experience.

When I am in a new job/role, the first thing I do is look for things I can automate. Recently I discovered that I’d be spending a lot of time changing command line arguments in the product I’d be testing and then reinstalling and checking a new build. Fine, except that unless you do a complete clean uninstall, the config persists. Not optimal. It’s hard to remember everything you’ve changed every time, so the very first thing I wrote was a quick python script (less than 100 lines, including comments) which reset all the variables, set some debug flags, installed the latest licence…

I don’t file bugs because of vestigial configuration settings.

Did I learn anything from writing this? I mean I’ve been writing Python for four years now, surely I’d know everything there is to know about… Oh wait, no I learnt about the subprocess library and I used some nice dictionary walking techniques. I’m proud of it too. I am emphatically not a programmer, I write some programs and scripts here and there to help with my everyday life. I’ve had no real formal training in programming and I know maybe three or four algorithms properly (and that due to an edX course in Algorithms). So for me, every time I open Sublime Text and start to bash out a Python script, it’s going to be a learning experience. That’s why I love it.

Do I fail? I fail hard. I fail often. I sit staring at my program wondering why nothing works for ages. Then I walk to get a coffee, or start to go home and it comes to me. Ask anyone who writes programs, those moments of enlightenment are worth all the frustration and puzzlement.

Though there’s a lot more enlightenment and a lot less boilerplate in Python!

Does anyone but a programmer, need to know how to program?

There’s an oft asked question in the testing community; “Do testers need to know how to program?” I feel that this is the wrong question. It’s often asked because knowing how to program will allow the tester (it is thought) to understand where the weak points in what they are testing exist, as well as aid them in their own work with automation and the like.

The better question is “What benefits does knowing how to program bring me?”

My instinctive answer is “it’s incredible how many benefits you get from learning how to program”, but instinct was evolved to stop you being eaten by a tiger or eating rotten meat. It’s really handy, but you can’t always rely on it.

So let’s break down the pros and cons.

I’ll start with the cons as I see them.

It takes a long time to learn to program well. It’s not just a case of reading the documentation and away you go. You need to practice and you need to learn whole new ways of thinking. If you want to learn to program really well, you need to learn a good deal of maths too.

Not only do you need to spend a long time on it, you’ll spend most of that learning the basics and doing things you don’t feel are especially useful. This can be very tedious.

You’ll need to learn your way past the limitations of the computer and/or language. Even things you think should be easy can have hidden complexity sometimes. Python division in 2.7, I’m looking at you*

If you don’t relish always failing forwards, you won’t enjoy programming. Programming exists on the edge of what you know, you’re always solving a new problem and that means continual failure.

The pros are easier for me to write. I’m biased.

In today’s world programming gives you access to a tool that will let you get a lot more from the evolving technology we surround ourselves with. You’ll be able to write the app you personally need, or grab an open source repo and play with the program until it works for you. Or if you’re like me, you’ll write your own toolbox when you enter a new role, which can really help you cut a lot of time out of testing and expose whole new areas of bugs that were hidden in the code.

As a tester the benefits are even more pronounced than for other people. Firstly it teaches you how a program, an OS, and a computer work. You might think you have a good idea of how a computer works, and maybe you do, but nothing teaches you the vagaries of an operating system like learning how to make it do anything useful. Knowing the basics of how to program will help to illuminate the dark parts of the program,where the bugs live. It helps even if you don’t read the actual code, because you know the areas where interactions are complex and so bugs are more likely to spawn.
Secondly it lets you read the code for your program, at least at a high level, and it’ll let you see where the developer(s) might have missed a trick or slipped a race condition into the program.

Thirdly, it lets you automate your checks. Now you might already have automation engineers and wonder if you really need to learn how to write your own checks. You do. You might not think you do, but you do. Automation engineers don’t want to write checks, they want to build and maintain frameworks. They probably don’t mind adding the odd check here or there, but really that’s not a great use of their time from their perspective, because it’s saving your time, not theirs. Writing your own checks means you’re certain what’s being checked too.

Essentially for me, it’s a given that learning to program is both beneficial and fun. I have never encountered a situation in which I’ve seriously thought “I wish I didn’t know how to program”, though I’ve seen some commits that have come close!

DISCLAIMER: I am a not a good programmer, but I am trying to get better every time I write a script. I am also a complete Python fanboy.

*In Python division takes two arguments and if both are integers, it’ll return an integer. So 5/2 = 2 in Python 2.7.

What to do when you’re thrown in at the deep end.

You should swim, it’s that or drown.

Sometimes you come into a company or team mid-sprint, the heat is on and no one really has time to hold your hand through the first few weeks. You’re expected to not only hit the ground running, but keep up with people who’ve been in the race for a while. This, to put not too fine a point on it, is daunting.

This recently happened to me, not through design, the people I am working with are good people with good intentions, but a combination of pre-booked holidays, intermittent internet for remote workers and my notice period on my previous job conspired such that the second week of my new job had me as the lone manual tester on the team, as we were pushing our release out the door. Oh and there was nearly nothing a new team member needed to know on our internal wiki.

I’d had a week of basically learning a little bit about the product as I ploughed through some bug verification and improvement integration. A lot of my time was spent learning what on earth our part of the product did and what the tests we were doing actually did and meant.

I was pretty lucky in that I’d worked with some of the developers before and I’ve been around the block long enough to know how to handle the kind of things that a standard release cycle will throw up. I also had a series of tricks, or should I say techniques so I look more refined, that allowed me to effectively assimilate a lot of information quickly and use them to make my way through the first couple of weeks. I’m going to share these amazing techniques today, gratis and for free.

My first trick was this: write it down. It doesn’t matter what it is, it doesn’t matter how you write it, just write it. You’ll get reams of information, far far more than the human mind can remember. Honestly, you get about 6-9 slots in current memory and unless you get a chance to push it to long term, it’ll be lost when your stack overflows*. This is a problem as you’ll probably be losing information in less than a minute at normal speeds. Writing things down shoves the problem aside and actually helps ameliorate it. When you write something down, you not only create an external store of information, but it also helps you commit it to memory**. It’s also often the case that if someone is teaching you something and they can see you writing, they will often pause, or slow down so you can finish writing. This helps to stem the tide of information overload. Now, all the research I’ve seen suggests that writing with a pen and paper is far better for information retrieval than typing into a laptop so if you can do it that way, definitely do. However my handwriting is a write only mechanism, so I use Sublime Text and a hierarchical directory structure which serves me well.

My second trick is to remember that you were hired/transferred because people think you can do the job well. It’s all too easy to underestimate yourself and think that everyone else is not taking into account the fact that you sometimes get distracted, or that you forget things, or that some days you just wish you were at home. Here’s the real kicker, those people are only judging you on your results. They don’t care how you get them, they don’t mind if you forget the odd thing, because they probably don’t notice it. What they see is what you achieve, not who you think you are. So not only can you do it, you can do it despite all the flaws you see in yourself. I came into testing through a 6 week temporary contract while I looked for a job. That 6 weeks became 4 years. I don’t have a degree, I don’t have any formal training in testing, I don’t even, hand on heart, think of myself as someone who can program. If you asked me who I was, it’d be a writer and gamer, a father and gardener, a cook and an entertainer. Yet here I was, dropped into a new job where I’d be doing some automation, lots of organising of tests and learning a new product on the fly. I honestly didn’t think I could manage it, but I always feel that way. I sat down each morning and I reminded myself that not only could I do it, but that everyone who hired me thought I could too. So either everyone was wrong, or my feelings were. Six weeks later, I think everyone else was probably right. You can do it too, write that down.

Thirdly, remember that while software products and development strategies might change – I just went from waterfall to agile – the core precepts of testing don’t change. You will be presented with many things you can’t immediately categorise as a bug or an expected behaviour. You freeze and worry that if you raise it as a bug, you’ll be wrong and seen as unreliable, or if you don’t it’ll be an actual bug and then you’re even more unreliable. What do you do? What would you normally do? You’d open your mouth (or chat client) and ask someone. No one sane, at all, would ever expect you to understand an entire software product on first glance, except the people running the Hello World! Company. Ask questions, ask them often, read existing bugs, get a feel for how people phrase things. You’ll also see a lot of terminology you don’t understand, things that are specific to this project or company. You will not understand these, again, ask. It’s here that writing it down can really help. You can write enough notes that the next person to join can merely read your notes on an internal wiki or the like and cut their learning time in half. This, in the hideous corporate speak of Silicon Valley, adds value. Always bear in mind that while what you’re seeing in the specific might be wildly different, if you abstract it a little, you’ll see it’s just a variation on things you’ve seen before.

Fourthly, don’t be afraid to fail. This has two meanings for a tester, it means be prepared to try new things without worrying that failure will somehow mar your perfect image. It can also mean not being afraid to say “No, this product does not pass this test, I will fail it”. There can be a strong temptation to curry favour among a new team by saying “this product is great, no problems”. It’s natural to want to be nice to new people, but you’re a tester and the best love a tester can give is tough love. You were hired to say “There is a problem we need to fix before we can let this out the door”, so if you find that problem you need to say it loud and proud. Your team will, eventually, thank you for it. Trying new things is also extremely good for you and certainly won’t make you seem bad if you fail at something new. Try writing a new test, try clarifying a test. If automation is in a language you don’t know (or you’re simply not a programmer), try adding a test. Ask for help, look for examples, but be willing to give it a go. The very worst that can happen is that you learn something, assuming you’re not playing in production of course!

Finally, my absolute killer technique, when you go home, leave work at work. I am terrible at this, I want to check emails, maybe kick a automated run off, perhaps read some of the test repositories. I have to fight it. I don’t always succeed. But turning off when you go home and focussing on your life will actually help your work the next day, and the day after that. Go home, talk to your friends and family about things that aren’t work. Read a book. Watch a movie. Sleep. Everything you do outside work that isn’t work will give your mind time to puzzle things out about work in the background. You’re helping the company and yourself by watching that Netflix series or reading the new book you’ve been waiting for. Obviously partying every night would take its toll, but be sensible and you’ll find that you’re a lot more productive and learn faster.

In conclusion then:
Write everything down
Everyone else judges you by your actions and results, they are more objective than you and they believe in you. Run with it.
Everything new is something old in a hat. You know how to deal with it, just look past the false mustache.
Failure is always an option and it’s not even a bad one at that.
Work to live, don’t live to work.

*http://psycnet.apa.org/journals/rev/63/2/81/
**http://pss.sagepub.com/content/early/2014/04/22/0956797614524581.abstract

Bash on Windows 10

If you’re following the tech press at all, you can’t have missed the news that Microsoft have, in partnership with Ubuntu, released bash on Windows 10.

 

However you might not know exactly what that means, or why you should care. Luckily I am one of the brave souls who play in the Windows 10 insiders Fast Track; which in practical terms means I get to reinstall Windows about once a week, but also means I get to play with next season’s toys today.

 

One of these toys is bash on Windows. This was fantastic news for me, as I’ve just changed jobs to a purely Windows company and was sorely missing the power of a proper bash terminal. But that’s too far into the story. Let’s start with what bash is.

The Bourne Again SHell, or bash, is a terminal emulator for Linux and Unix systems that is also a scripting language for the same emulator. If you’re a Windows person, think cmd or Powershell, but much more powerful and with an absolute plethora of tools to make a developer or tester’s life easier in the command line. Now this is not the first bash shell on Windows, far from it. There’s been Cygwin and GitBash for years and by and large they’ve done a decent job. But this is quite different. Cygwin and other bash shells on Windows have, until now, recompiled the binaries for their tools into Windows exes, this means you can’t just take any off the shelf Linux or Unix tool and just expect it to work, someone has to have worked at it to make it run on Windows. This version from Canonical and Microsoft is something quite different, quite special and just a little bit ironic*. What it relies on is the “Windows Subsystem for Linux” (which to my mind should be the Linux subsystem for Windows, but hey). This subsystem is essentially a compatibility layer, which takes OS calls from Linux binaries and converts them on the fly into their equivalent Windows calls.

So why is this special? It means you can take any old Linux binary for x86-64, and run it, assuming the dependencies are satisfied. Any old binary like, say, apt-get or dpkg. Now if you’re not familiar with Linux, you might not have heard of a package repository. This is like the Windows store, except really good and people use them. Canonical release Ubuntu, and Ubuntu has an absolutely massive set of packages in their repositories. This version of bash has access to those repositories.

This is like adding tens of thousands of tools to Windows, in one go.

 

So, who cares? It’s not like you needed these tools before, why do you need them now?  Well I care, I care a lot.  I care enough to write this blog post. Here’s why. These tools are industry standards, and they do things you might not have believed possible. The core philosophy of Unix is to do one thing and do it well, and these tools do exactly that. There’s things like ls, which is vaguely analogous to dir on Windows. It lists the files in a directory, so far so humdrum. Then there’s mv which moves files, just like Windows’ move. Nothing to get excited about here. Then there’s cat, which displays the contents of a file, just like type on Windows. But then, then we can move on to more interesting utilities, like grep, which searches for a pattern (and it can be a regular expression, a sentence, a string or even just a particular number) and shows you where it found it. There’s sed, which is a Stream EDitor, that looks for patterns and changes what it finds. So far, nothing earth shattering.

But bash has a trick up its sleeves, it’s a simple trick, but it’s an absolute corker. You can take the output from one command and use it as the input for another, and then the output from that command can be used as the input for another. So you go to your photos directory and you have a look around. You type ls and get back a list of all the files in that directory. But you’re only interested in ones you took with Tony the Tiger, you remember naming those Tony_tiger_XX.jpg where XX is a number. So you add the pipe “|” to the end of the ls command and then add another command,

grep Tony_tiger

. This gives you the command

 ls | grep Tony_tiger

and it’ll only list the files that start with Tony_tiger. But then you want to move them to another folder, say a Tony_Tiger folder. So you make the folder,

mkdir Tony_Tiger

(same command as on Windows), then you start to get creative with something called xargs. xargs takes standard input and uses it as a variable in a command. So to move all files with Tony_tiger to the Tony_Tiger directory, you can use this command

ls | grep Tony_tiger | xargs -I{} mv {} Tony_Tiger/

(You can actually do this with the metadata and rename on the fly rather than file names using another utility, but it’s  too involved for this explanation, though infinitely more useful)

So while that example was fairly facile, you can see that with this piping, you can achieve some remarkably powerful effects with a very concise command, very quickly and efficiently. Now I know some purists out there are going to say that Powershell can do the same thing, which it sort of can. But for me Powershell doesn’t have the plethora of tools available, not all of its tools work in stream mode (dir, for example blocks, so it has to finish dir before it’ll release the results to the pipe), also it works in objects not text, which makes things a bit different.

 

So now you know what bash is, why you might want to use it and a little bit about how it works. Now let’s talk about the actual subject of the post, bash on Windows 10.

I’ve been playing with it for a few hours now and I’ve found some of the limitations of this new bash. As it stands there are swathes of the standard Linux file system missing or not mounted. The reason for this is that Windows isn’t Linux, so a lot of the layer is faking things that don’t exist. The file systems are completely different, how they treat things is completely different. Linux sees everything as a text file, sort of, so you plug a usb stick into your machine and suddenly your /dev/ directory has a ttyUSB0 file. Windows doesn’t exactly work like that, it doesn’t have a central store of files representing every piece of hardware attached to the system. Linux stores active process and system information in /proc, Windows doesn’t have that exactly. Linux stores executables (or symlinks to those executables) in /bin or /usr/bin (or indeed in /usr/sbin), Windows leaves the executables in various folders in Program Files along with the data they rely on. The two systems are very different, so not everything works.

I can’t do anything that requires netlink sockets, so I can’t ping, I can’t see my IP, I can’t do a lot of file system based stuff, like locate or df -h. These things simply don’t work, the systems to support them simply aren’t in place.

Programs like elinks (a terminal based web browser) and tmux (a Terminal MUltipleXer) don’t work quite as expected.

There’s no X server, nor even a Mir server. This means there’s no graphical utilities available. (Though I’ve seen someone use cygwin’s x server to run Ubuntu bash utilities already. Which is awesome, but not ideal)

What does work?

One hell of a lot. The mere fact that I can use standard bash tools on the windows file system means that I can suddenly have some handy scripts that will do a lot of heavy lifting for me. There’s cron, so I can schedule these scripts to run at certain times and most importantly, there’s the entirety of the repositories.

wget works, curl works. So while I can’t ping a website, I can still grab its information. Python comes pre-installed in both 2.7 and 3 versions. An SSH server’s installed, which is about the most monumental thing ever. Cygwin’s had one for years but it’s been quite ropey in use for me, and very slow. I can get git and it’s about a zillion times faster than through gitbash or cygwin in my testing. It’s got incidental little tools like curl and wget and awk and sed and… well it’s full of all the things I’ve taken for granted in the last four years where I’ve mainly been using Linux.

Is it perfect? Nope. Is it a replacement for a dedicated Linux machine? Certainly not.

Is it worth it? Yep. It removes one more layer of friction between a Windows machine and Linux machines. It makes it so you can ssh into your raspberry pi in a cmd prompt happily. It means you can use editors that format line endings properly. You can cat and grep files and search folders for strings based on regexes. You can do so much today that you could not do last week and you can do it in a supported way.

Do I recommend it? It depends. If you’re used to Linux utilities, but you work in Windows? Yes, yes, yes a thousand times yes. If you want to learn some Linux commands without the hassle of dual booting or the overhead of a VM, it’s definitely worth a go. If you never venture into the command line anyway, it’s not going to add much to your world, probably best to let it slide by. If you want a full Linux system with every possible utility at your fingertips? Nope, it’s not even close, but I hope it’ll get closer.

The thing to remember is that it is quite definitely a work in progress, nothing is quite finished and there are rough edges everywhere you look. It’s an amazing first step though and I am really looking forward to using it until the end product.

 

*It’s ironic because for decades, Linux has run Windows executables using something called WINE (which stands, recursively, for Wine Is Not an Emulator). WINE is a compatibility layer for windows programs on Linux. It’s the exact mirror of this Windows Subsystem for Linux.