For the past few weeks a number of programmers and myself have been tasked to build an initial prototype for a system rewrite project, handed to us by management. The merit of such project is a matter of discussion for another day; for now it is enough to say that the team has been given a difficult challenge, but at the same time excited about the lessons we knew we will gain from such an adventure.
There’s been several takeaways already in terms of technology know-how – dockerized applications, front-end development with Vue, repositories as application vendor dependency, microservices – just several of the things we’ve never done before.
But the great takeaway so far is the joy of literally working together, inside a room away from distractions, the team working on one task at a time, focused, taking turns writing application or test code on a single machine, continuously discussing options and experimenting until a problem is solved or until it is time to take a break. We instantly become aligned at what we want to achieve, we immediately help teammates move forward, we learn from each other’s skills and mistakes, we have fun. It’s a wonder why we’ve never done much of this before. Perhaps it’s because of working in cubicles. Perhaps it’s because there’s nearly not enough available rooms for such software development practice. Perhaps it’s because we’ve never heard anything about mob programming until recently.
I’m sure it won’t be everyday since we have remote work schedules, but I imagine the team spending more days working together like this from here on.
In testing software, automation is a tool that helps us re-run whatever repeatable checks we have on an application under test. We automate because we never have enough time to re-test everything by hand, and exploring the unknown parts of the apps we test is a far better use of our testing skills than following scripts. To automate is doing one thing right, within context, if it provides us the feedback we need. And that feedback we think we need from automation depends on what suites of tests are best repeated again and again, as well as what sort of tests costs more than the value they give.
There’s also tons of tools that helps us build good quality software. Even though we build more complex applications now than before, we have frameworks, libraries, intelligent IDEs, and other tools to help us spin up apps on a whim now too, ready to be modified as we see fit. Choosing the proper tools for the job is doing another thing right. But before we write any code, we need to be sure about the actual problem we are solving for our customer.
Yes, we need to do things right, from the get go if possible. They help us progress from one point to another faster than otherwise. However, I think it’s more important that we continuously take the necessary time to review whether we are doing the right things too, more important to actually get feedback and solve problems than merely adding tests and features.
Dale Carnegie’s “How to Win Friends and Influence People” is a classic, and I did not understand what that meant until now, after reading the book. It has survived the test of time, and the lessons in it still applies to all of us today. It really is a treasure trove of actionable advice about forging friendships and leading people, and I’ve come to see why some of my way of doing things have worked for me all this time. Better, I’ve found places where I could use more practice and improve.
Here are some favourite lines from the book:
- Let’s realise that criticisms are like homing pigeons. They always return home. Let’s realise that the person we are going to correct and condemn will probably justify himself or herself, and condemn us in return.
- There is only one way under high heaven to get anybody to do anything. And that us by making the other person want to do it. The only way I can get you to do anything is giving you what you want.
- We nourish the bodies of our children and friends and employees, but how seldom do we nourish their self-esteem? We provide them with roast beef and tomatoes to build energy, but we neglect to give them kind words of appreciation that would sing in their memories for years like the music of the morning stars.
- If there is any secret to success, it likes in the ability to get the other person’s point of view and see things from that person’s angle as well as your own.
- Keep in your mind on the great and splendid things you would like to do, and then, as the days go gliding away, you will find yourself unconsciously seizing upon the opportunities that are required for the fulfilment of your desire. Picture in your mind the able, earnest, useful person you desire to be, and the thought you hold is hourly transforming you into that particular individual.
- He had wanted merely a friendly, sympathetic listener to whom he could unburden himself. That’s what we all want when we are in trouble. That is frequently all the irritated customer wants, and the dissatisfied employee or the hurt friend.
- So if you aspire to be a good conversationalist, be an attentive listener. To be interesting, be interested. Ask questions that other persons will enjoy answering. Encourage them to talk about themselves and their accomplishments. Remember that the people you are talking to are a hundred times more interested in themselves and their wants and problems than they are in you and your problems.
- Anyone who takes the time to disagree with you is interested in the same things you are. Think of them as people who really want to help you, and you may turn your opponents to friends.
- You can tell people they are wrong by a look or an intonation or a gesture just as eloquently as you can in words – and if you tell them they are wrong, do you make them want to agree with you? Never! For you have struck a direct blow at their intelligence, judgment, pride, and self-respect. That will make them want to strike back. But it will never make them want to change their minds. You may then hurl at them all the logic of a Plato or an Immanuel Kant, but you will not alter their opinions, for you have hurt their feelings.
- If you are going to prove anything, don’t let anybody know it. Do it so subtly, so adroitly, that no one will feel that you are doing it. You cannot teach a man anything; you can only help him to find it within himself.
- I am convinced now that nothing good is accomplished and a lot of damage can be done if you tell a person straight out that he or she is wrong. You only succeed in stripping that person of self-dignity and making yourself an unwelcome part of any discussion.
- If a man’s heart is rankling with discord and ill feeling toward you, you can’t win him to your way of thinking with all the logic in Christendom. Scolding parents and domineering bosses and husbands and nagging wives ought to realize that people don’t want to change their minds. They can’t be forced or driven to agree with you or me. But they may be possibly led to, if we are gentle and friendly, ever so gentle and ever so friendly.
- No one likes to feel that he or she is being sold something or told to do a thing. We much prefer to feel that we are buying of our own accord or acting on our own ideas. We like to be consulted about our wishes, our wants, our thoughts.
- What do you think he found to be the most motivating factor – the one facet of the jobs that was most stimulating? Money? Good working conditions? Fringe benefits? No – not any of those. The one major factor that motivated people was the work itself. If the work was exciting and interesting, the worker looked forward to doing it and was motivated to do a good job.
- This is what every successful person loves: the game. The chance for self-expression. The chance to prove his or her worth, to excel, to win. That is what makes foot-races, and hog-calling, and pie-eating contests. The desire to excel. The desire for a feeling of importance.
- He always gave people the opportunity to do things themselves; he never told his assistants to do things; he let them do them, let them learn from their mistakes. A technique like that makes it easy for a person to correct errors. A technique like that saves a person’s pride and gives him or her a feeling of importance. It encourages cooperation instead of rebellion.
- If you want to improve a person in a certain aspect, act as though that particular trait were already one of his or her outstanding characteristics. Assume a virtue, if you have it not. Assume and state openly that other people have the virtue you want them to develop. Give them a fine reputation to live up to, and they will make prodigious efforts rather than see you disillusioned.
- Tell your child, your spouse, or your employee that he or she is stupid or dumb at a certain thing, has no gift for it, and is doing it all wrong, and you have destroyed almost every incentive to try to improve. But use the opposite technique – be liberal with your encouragement, make the thing seem easy to do, let the other person know that you have faith in his ability to do it, that he has an undeveloped flair for it – and he will practice until the dawn comes in the window in order to excel.
- It isn’t what you have or who you are or where you are or what you are doing that makes you happy or unhappy. It is what you think about it. There is nothing either good or bad, but thinking makes it so.
A software development team is composed of people, a combination of of programmers, testers, designers, and product owners. One team is visibly different from another because they have different people working in them, although both teams work in the same organisation and share the same mission. One group may be dealing with passionate but inexperienced new hires, another may be led by an introverted and soft-spoken senior, another team could be a lot more experienced with automating things, one team is probably better with team communication than others. Each team has a life of its own, always growing up, always trying to find out what specific problems itself has and what values it can contribute to the organisation, evolving day after day.
We understand that everyone is similar yet different from each other. Why is it then that we often insist in managing them with a one-size-fits-all process? Or am I missing something? I understand that we want teams to get better at what they do, we want them to release software faster, with better quality, but do we really think that one particular process works for everyone? Instead of that, shouldn’t we just immerse ourselves in a team, one after another, observe, ask where they are and where they want to go, talk to them, share experiences, help them solve problems, care for them, let them grow into a family with us? It seems to me that every time I get to join a team I think about the people in it first, no particular fixed process in mind, and we find out what works for us as we go, together.
It’s been a while since I’ve shared interesting articles and recordings about topics surrounding software development and testing.
Here are a few videos, for the curious:
- Continuous Delivery – Sound’s Great But It Won’t Work Here (by Jez Humble, about continuous delivery, the excuses organizations tell people when they fail to implement it, and what those excuses actually mean)
- There and Back Again – A Hobbit / Developer / Tester’s Journey (by Pete Walen, on how software was built in the old days, how testing and programming broke up into silos, and a challenge for both parties to go back at excelling at each other’s skills and teaming up)
- Feature Injection (by Chris Matts, about business analysts and tea bags, understanding that requirements are just dependencies, and finding out where the value is in requested features by asking for examples)
- A Day of Mob Programming (by Woody Zuill, on mob programming, and how taking a whole team approach to coding can help us align and build better software together)
- Testability vs Automatability (by Alan Richardson, about the differences between testability and automatability, what each term actually mean, and recognizing how specific words can help people tell stories better or not)
It was only several years ago when I started writing Selenium tests, first with Selenium IDE, then in Java with Webdriver, then in Ruby with Watir. Now I don’t write a lot of Selenium tests anymore, ever since I found out that it is often better (faster and more stable) to write automated checks for application features through the API. Or through unit tests. Selenium has its place in checking user flows or automating the UI, but only if I have to, if its value exceeds that of its costs. There lies an important lesson in automation: there is not a single tool that does it all. It is us who decides which tool to use for a particular test, and it helps to understand if a tool fits the specific use case.
And I think I’ve familiarized myself with a number of tools this year: Postman for API testing, Winium for automating Windows applications, BackstopJS for open-source visual testing, Cloud9 for cloud-based software development, Phonegap for HTML-based mobile app development, Docker for building shareable self-contained images of applications for development or testing, PHP testing tools (PHPUnit, Guzzle, Behat), and source code linting tools like Rubocop for Ruby. I’m not a master of these tools, but I know enough to be able to decide whether I need them (or not) for a particular thing I want to achieve. They’re in my tool belt.
Needless to say, I have outgrown the hype of automation. It is programming and tooling at its core. It helps us perform repeatable tasks without breaking a sweat, not limited to testing apps, if done with care. It is not easy. It can be rewarding. It all starts with a deep understanding of what definite task or problem actually needs solving.
And this year’s experiences has lead me to better grasp the nuances of software development, which is actually a problem of people, of teams and their habits and biases. Our team certainly has its defaults, some of which are not helping us get better at what we do. And as such from here on I’d like to contribute in key areas I believe our programmers have not had much time to think about because of project deadlines and resource constraints – dockerized application environments and shift-left testing – solutions for providing testing feedback earlier in the software development cycle, which in turn can help us build better apps and release faster.
Last Wednesday afternoon I anxiously asked my boss for permission to make changes on our application code repository. I said I wanted to try fixing some of the reported bugs listed on our tracking system, if there are no other resources available to pass them to. I made a case about myself not posing any problems because of the code review process built into our repository management tool, that there’s no reason for me to merge any changes without getting feedback from a senior developer first.
He smiled at me and gleefully said “Go ahead. I’m not going to stop you.“, to which I beamed and heartily replied “Thanks, boss!”
This is a turning point in my software testing career, to be able to work on the application code directly as needed. It is actually one of my biggest frustrations – to not be able to find out for myself where the bug lives in the code and fix them if necessary. It’s always a pain to be able to do nothing but wait for a fix, and for a fix to be dependent on the resources available. In my head I think that I’m available and maybe I can do something, but I don’t explicitly have access to the application itself and the code that runs it so I can’t do anything until I have the rights to do so. That’s how it always been. Software testers are often not expected to fiddle with code, at least in my experience, especially in the past where automation was not yet known to be useful as a testing tool. Now that I have the skills and the permission to work on the application repository, I feel that my reach for making an impact on application quality has now expanded remarkably well.
Now bug-fixing is not software testing work in the traditional sense. But I figured there’s no harm in trying to fix bugs and learning the nitty-gritty details of how our legacy applications actually run deep in the code. I believe that learning technical stuff helps me communicate better with programmers. It helps me test applications in a more efficient manner too. Of course I have to consistently remind myself that I am a software-tester-first-programmer-second guy and have to be careful not to fill my days playing with code and forgetting to explore our applications themselves. That said, there are ideas I really want to experiment within our software development process, towards the goal of improving code quality and feedback, and I can only tinker with those ideas inside the application repository itself. Dockerized testing environments, code linting, and unit tests are three things I want to start building for our team, ideas that I consider to be very helpful in writing better code but has not been given enough priority through the years.
I think I’m still testing software, just extending the knowledge and practice of the various ways I perform testing.