Tuesday, March 28, 2017

Changing Change Aversiveness

"I want to change the automatic installations to hourly over the 4-hour period it has been before". I suspected that could cause a little bit of discussion.

"But it could be disruptive to ongoing testing", came the response. "But you could always do it manually", came a proposal for alternative way of doing things.

I see this dynamic all the time. I propose a change and meet a list of *but* responses. And at worst they end up with *it depends* as no solution is optimal for everyone.

In mob programming, we have been practicing the idea of saying yes more often. When multiple different ways of doing something are proposed, do all. Do the least prominent one first. And observe how each of the different ways of doing teaches us not only about what worked but what we really wanted. And how we will fight about abstract perceptions without actual experience, sometimes to the bitter end.

This dynamic isn't just about mob programming. I've ended up paying attention to how I respond in ways that make others feel unsafe in suggesting the changes, after I first noticed the pattern of me having to fight for change that should be welcomed.

Yes, and... 

To feel safe to suggest ideas, we need to feel that our ideas are accepted, even welcome. If all proposals are met with a list of "But...", you keep  hearing no when you should hear yes.

The rule of improv "Yes, and..." turns out to have a lot of practical value. Try taking whatever the others suggest and say your improvement proposal as a step forward, instead as a step blocking the suggestion.

Acknowledge the other's experience

When you hear a "But...", start to listen. Ask for examples. When you hear of their experiences and worries, acknowledge those instead of trying to counteract them. We worry for reasons. The reasons may be personal experiences, very old history or something that we really justifiably all should worry about. The perception to whoever is experiencing a worry is very real.

A lot of times I find that just acknowledging that the concern is real helps move beoynd the concern.

Experiment

Suggest to try things differently for a while. Promise to go back or try something different if this change doesn't work. And keep the promise. Take a timebox that gives and idea a fighting chance.

People tend to be more open to trying things out than making a commitment on how things will be done in the long term. 

Monday, March 27, 2017

The Myth of Automating without Exploring

I feel the need of calling out a mystical creature: a thinking tester who does not think. This creature is born because of *automation*. That somehow, because of the magic of automation, the smart, thinking tester dumbs down and forgets all other activities around and just writes mindless code.

This is what I feel I see when I see comparisons of what automation does to testing, most recently this one: Implication of Emphasis on Test Automation in CI.

To create test automation, one must explore. One must figure out what it is that we're automating, and how could we consistently check the same things again and again. And while one seeks for information for the purposes of automation, one tends to see problems in the design. Automation creation forces out focus in detail, and this focus in detail that comes naturally with automation sometimes needs a specific mechanism when freeform exploring. Or, the mechanism is the automation thinking mindset. 

I remember reading various experience reports of people explaining how all the problems their automation ever found were found while creating the automation. I've had that experience in various situations. I've missed bugs for choosing not to automate because the ways I chose to test drove my focus of detail to different areas or concerns. I've found bugs that leave my automated tests in "expected fail" state until things get fixed.

The discussion around automation is feeling weird. It's so black and white, so inhumane. Yet, at core of any great testing, automated or not, there is a smart person. It's the skills of that person that turn the activity into useful results. 

Only the worst of the automators I've met dismiss the bugs they find while building the automation. Saves them time, surely, but misses a relevant part of feedback they could be providing. 


A Regular Expression Drive-By

I was working in strong-style pair on my team's test automation code last week, to assess candidates to help us as consultants for a short timeframe of ramping up our new product capabilities. The mechanisms of "an idea from your head to the computer must go through someone else's hands" lends itself well for assessing both skills and collaboration. At first, I would navigate on the task I had selected - cleaning up some test automation code. But soon, I would hand the navigation over to my pair and be the hands writing the changes.

There was this one particular line of code that in both sessions caught my eye and was emphasized by the reaction of my pairs: "This should have a code comments on it", "Ehh, what does this do, I have no idea!". It was a regular expression verifying if a message should be parsed to passed or failed but the selection of what the sought for keyword was was by no means obvious.

I mentioned this out loud a few days later, just to seek for confirmation that instead of the proposed code comment, it should really just be captured in a convenience method that would have a helpful name. But as we talked on the specific example, we also realized that it would make sense to add a unit test on that regular expression to explain the logic just a bit more.

The unit test would start failing if for any reason the messages we used to decide on pass/fail would no longer be available, and would be more granular way of identifying where the problem was than reading the logs of the system test.

A regular expression drive-by made me realize we should unit test our system tests more. 

Friday, March 24, 2017

Find the knobs and turn them

"What happened at work?" is a discussion I get to have daily. And yesterday, I was geeking out on installing and configuring a Windows Server as a domain controller, just so that I would have one more route to put things on a list that our product was supposed to manage.

Instead of talking about the actual contents, the discussion quickly moved to meta through pointing out that a lot of my stories of what I do for work include finding this button, lever or a knob, and twisting, pushing, pulling even intentionally isolating it. I find things that give me access to things others don't pay attention.

"I'm sure a developer did not take two hours to set the server up just for this test", I exclaimed. And continued with "while I was setting this up, I found four other routes to tweak that list." It was clear to me that if there was anything interesting learned from the 1st route I was now working on, the four others would soon follow.

Think about it: this is what we do. We find the knobs of the software (and build those knobs to be available in the system around our software) just so that we see, in a timely fashion, what happens when they are turned.

It turns out you may find some cool bugs thinking like this.

From appreciation of shallow testing towards depth

So, Maaret Pyhäjärvi is an extraordinary exploratory tester. ... She took ApprovalTests as a test target. She's like "I want to exploratory test your ApprovalTests" and I'm like "Yeah, go for it", cause it's all written test first and its code I'm very proud of. And she destroyed it in like an hour and a half. She destroyed in in things I can't unit test. One of the things she pointed out right away was "Your documentation is horrible. You're using images that you can't even copy and paste the examples from". And I'm, like, "yeah, that's true". And then she's like "Look at the way you write this API, it's not discoverable". And that's a hard thing for me to deal with because for me, I know exactly where the API is. One of the things I constantly struggle with is beginner mindset. And it's so easy to lose that and then never appreciate it in  the beginning. You're like "no, idiot, your supposed to do it this way". So this idea that my names are not discoverable is not something I could unit test but she was able to point out right away. And after pointing it out, and sort of arguing a little bit, she did this thing where she... She did in a session. I attended the session, but everybody is doing a mob exploratory testing an now I'm watching like 10 people not being able to find a reporter. It's nothing like watching people use your product and not be able to talk to make you appreciate you've done it wrong. I was like "oh, this is so painful, I never want to see that again".

What I found is that it used to be the case that we would write code and it was horrible. It was buggy and just so full of problems. And there was so many bugs where what we intended to occur wasn't what was happening, so that all that testing was was checking that what the programmer intended what the code did. This is all we had time for. As we started doing unit testing and automated testing, and test first, those problems started to go away. So now what the code does is what we intend it to do. And then it turns out there is this entire another world of is what you intended what you want. And it turns out, that's still a remarkably complex world. So you don't want to spend your time fighting with what I intended is not what the code does, so you need the unit test for that. But we also need this much bigger world of is what I intended what I actually want. What are the unforeseen consequences of these rules. That starts moving to exploratory testing and monitoring. Which is effectively exploratory testing via your users. "

The story above a great story about how one programmer learned there was more to testers contributions that he could have seen. It's great hearing Llewellyn pass hints in a meetup to other programmers such as yesterday: "Your testers know of more bugs than what they tell you. Even though it feels they tell you a lot, they still know more. Ask them, don't just wait them to tell you."

Some of the emphasis in the above text are for adding more to the story.

1,5 Hours is Shallow Testing and Excludes Earlier Learning

While a tester can in "just hour and a half" get you to rewrite half of your API, there's more depth to that testing than just the work immediately visible. Surely, when I started testing ApprovalTests, I already knew what that was supposed to be for and the hours in the background getting familiarized count in what I could do. I had ideas on what a multi-language API in IDEs should be like, and out of my 1,5 hours, I still used half an hour on two research activities: I googled what a great API is like and I asked user perspective questions from Llewellyn to find out what he thinks ApprovalTests Approvals and Reporters do - collecting claims. 

With the claims in particular and consistency across languages taking into account language idiosyncrasies, I could do so much more with deep exploratory testing he has not yet seen. That's what I do for my developers at work.

Things You Can and Can't Unit Test For

While discoverability of an API in an IDE does not strike as an idea to unit test for, after you have that insight, it is something you can change your unit tests to include. Your unit tests wouldn't notice if the API turns again hard to but it would give you the updated control over what you now intended it to be. 

The reason I write of this is that I find that a lot of times when I find something through exploration, I have a tendency of telling myself that this insight couldn't be a unit tests because I found it in the system context. After an insight exists, we could do a lot more on turning those insights into smaller scale and avoid some of the pain at least I am experiencing through system level test automation. We need to understand better (through talking about it) what is the smallest possible scope to find particular problems. 

When Making a Point, Try Again

The story above hints on arguments over the API, that were much less of arguments than discussions on what is practical. Changing half of your API after you have thousands of users isn't exactly a picnic in the park and as a tester, I totally get that many organizations don't really care about that feedback on discoverability when it is timed wrong - get your testers involved before your users fix your world. 

I would believe I got my message through with Llewellyn already telling my experience. But surely, I do have a tendency of advocating for the bugs I care for, and getting an experience with your real users trying to use your software is a powerful advocation tool. 

As an exploratory tester, I could write a chapter about ways I've tried advocating for things that my devs don't react on, just to be sure we understand what we don't fix. Perhaps that's what I do next for my exploratory testing book on leanpub

Where Most of the Software World Is

Getting to work with developers who do test-driven development and test with the commitment Llewellyn shows is rare. When in the second part of the exerpt he talks about the testing for what programmer intended for, I can't help but realize that out of the hundreds of developers I've had the pleasure working with, I can count the ones who do TDD with one hands fingers. 

Let's face it. The better of us unit test at all. And even that is not a majority still. And generally, most of us still suck at unit testing. Or even if not personally, we know a friend who does. 

When I explore, it is a rare treat to have something where the software does *even* what the programmer intended to. So I start often with understanding that intent through exploring the happy, expected paths. I first have empathy of what the world could be if the programmer was right in what he knew today while implementing this. 
But even the TDD-ers, I approach with scepticism.  Llewellyn meetup talk yesterday introduced Asserts vs. Approvals and he had this slide comparing someone's Assert-TDD end result to his Approvals-TDD end result. 
He pointed out that the tests on the left (Asserts-TDD) missed a bug in the code for value 4 being represented as IIII, whereas the test on the right (Approvals-TDD) found that missed bug run against the other's code. 

As a tester, I would have been likely to check how the developer tested this. My life would have been a lot simpler reading the Approvals-file with formatting and scenarios collected. But even if I did not read the code, I would be likely to have gone to sample values that I find likely to break. 

What you usually get in TDD is your best insight. And our shared insight, together, tends to be stronger than yours alone. I tend to generate different insight when my head is not buried in the code.





Wednesday, March 15, 2017

Don't pay to speak, get paid to speak

I strongly believe the world of tech conferences needs to change, and the change I call for is that whoever the conference organizers deem good enough to step on their podium to speak, should not have to pay to speak. And when I talk about paying to speak, I speak of expenses.

In case of paying for travel expenses, and encouraging the cheapest possible travel, there's a second step. When booking early, pay back early. Don't use your speakers as a bank and pay back after the conference.

I work towards changing these two.

Other people ask for more, and I would love to join them. They ask to be paid to speak. They ask for the time they put on preparing to be compensated. And since the work you do is not preparing the talk, it's becoming the person that gets on that stage, the speaking fees should be relevant.

In paying, a big injustice is when some people get paid differently than others. The injustice of it just gets bigger when conferences give replies like this on paying some but not others.
As a conference organizer, I want to share my perspective.

I set up a conference that:

  1. Pays travel expenses of the speakers. All the speakers.
  2. Profit shares with all the speakers. Keynotes get 5* what a 30-minute slot speaker gets. 
The second happens only if there is profit. And I work hard to make profit. In 2017, I failed. I made losses. 

If I would have committed early on to paying my speakers, I would have lost more than 20k that I lost now. This loss is insignificant as it is an investment into a great conference (and great it was!) and an investment in making things right in the world of speakers. But imagine if I had a thousand euros to pay to each of my speakers, I would be down 30k more. 

What I failed in was marketing. Getting people to learn about the conference. Yet, I feel that whoever came are the right people. 


To make marketing easier, famous names help. Some famous names are willing to risk it to not be paid for their time, and I'm very grateful for that. But others have a fixed price range, paid in advance. When as an organizer you want to invite one like that, you fill the other similar slots with people who are not the same: people who don't insist on being paid fairly. But lying about it is just stupid. The speakers talk. And should talk more in the future.

As an organizer, I rather leave out the superstars if the same fees principle is a problem for them. And honestly, it is a problem for many of our tech superstars. But things change with conferences only if we change them. One conference at a time. 

Meeting is not just a meeting

We're sitting in a status / coordination meeting, and I know I don't look particularly happy to be there. The meeting, scheduled at 3pm has been lurking on my mind the whole day and for the last hour before it, I recognize I have actively avoided doing anything I really should be doing. And what I really should be doing is deep thinking while testing. I feel there must be something wrong with me for not being able to start when my insides are seeing the inevitable interruption looming.

It's not just the inconvenient timing at the seeming end part of my day that has negative impacts on my focus. It's also the fact that I know the meeting is, in my perspective, useless and yet I'm forced there trying to mask most of my dislike. It drains my energy even further.

In the ten years of looking at agile in practice, one of my main lessons has been that planning the work is not the work. I can plan to write a hundred blog posts, and yet I have not written any of them except for a title. I can plan to test, yet the plan never survives the contact with the real software that whispers and lures me into some cool bugs and information we were completely unaware of while planning.

I love continuous planning, but that planning does not happen in workshops or meetings scheduled for planning. It happens as we are doing the work and learning. And sitting in a team room with insightful other software developers, any moment for planning is almost as good as any other. The unscheduled "meeting" over a whiteboard is less of an interruption than the one looming in my schedules.

I know how I feel, and I've spent a fair deal of time understanding those feelings. I know how to mask those feelings too, to appear obedient and, as a project manager put it, "approach things practically". But the real practice for me is aspiring to be better, and to accommodate people with different feelings around same tasks.

Planning is not doing the work. But it does create the same feeling of accomplishment. When you visualize the work, you start imagining the work is done. And if you happen to be a manager who sits through meetings day in and out, the disruptiveness of a meeting in schedule isn't as much as it is when you are doing the work.

I used to be a tester. Then I became too good to test, and took the role of a manager. I was still good, just paying attention to different things. But the big learning for me came when I realized that to have self-organized teams as we introduced agile a decade ago in the organization, I was a hindrance. My usefulness as a manager stopped the people from doing the work I was doing. Stepping down and announcing the test manager role gone and just teaching all the work I had been doing to teams was the best choice I've done.

And it made me a tester again. But this time around, I don't expect a manager to be there. I expect there's a little manager in every one of us, and the manager in others help me manage both the doer and the manager in me.

The two roles were different for me. And awareness of that keeps me wary of meetings.

Monday, March 13, 2017

A Mob Testing Experience

During my 6 months at the new job, I've managed to do Mob Testing a few times. Basically the idea is that whenever I sink into a new feature that needs exploring, I invite others to join me for the exploration for a limited time. I've been fascinated with the the perspectives and observations of the other testers I've had join me, but these always leave me wanting after the Mob Testing experiences I had at my earlier place of work. There not only testers joined (well,  there were no testers other than myself) but we did the tasks together with the whole team, having programmers join in.

There's a big difference on if you're mob testing amongst testers (or quality engineers as we call them) or if you're including your teams developers and ever product owners. And the big difference comes from having people who need to receive the feedback testing is providing sharing the work.

With 6 months approaching, I'm starting to see that my no-so-subtle hints on a regular basis are not taking adapting mob testing / programming further. But it became funny at a point I taught developers from another organization who started off with the practice, and only through their positive reports someone relevant enough to push people to try it took initiative. There's an infamous old saying of no one ever being a prophet on their own land, and that kept creeping up to my thoughts - I became part of furniture, "always been here" surprisingly quickly. And I don't push people to do things they don't opt in to.

But finally last week's Wednesday, while my own personal team did not opt in, the team next door did and invited me to join their experience. With two application developers, two test developers and two all-around test specialists, we took the time to mob for about 5 hours during the day.

The task we were working on was a performance testing task, and the application developers were not in their strong area. We worked on extending an existing piece of code to a specific purpose, and the idea of the task was available to start our session. There were a few particularly interesting dynamics.

When in disagreement, do the less likely one first

About half an hour into our mobbing, we had a disagreement on how we would approach the extending of the code. We just did not disagree what would  be the right thing to do as the next step. The two of us who were familiar with what the goal of what we were doing had one perspective. And another suggested doing things differently, in a way that in the moment felt it made little sense to us.

I realized that were were quickly going into discussion mode, convincing the other of what the right thing was - at a time we really knew the least. The other suggestion might not sound like the best idea, so we played a common rule to beginning mobs: "Do the less likely first, do both". Without continuing the discussion, we just adjusted the next step to be one that the other, in minority, felt strongly enough to voice.

And it turned out to be a good thing to do in a group. As it was done, the work unfolded in a way that did not leave us missing the other option.

Keep rotating

Between hours 2-3, two of the six mob participants needed to step out into another meeting. I was one of these two. For first two hours, we had rotated on a four minute timer and pushed the rule of having a designated navigator. As I came back from the meeting, the rotation had fallen off as the mob had found relevant bugs in performance and had two other people join in as lurkers on the side of the table, monitoring breaking services in more detail. The lurkers did not join the mob, but also the work got split so that the common thread started to hide.

Bringing back rotation brought back the group thread. Yet it was clear that the power dynamic had shifted. The more quiet ones were more quiet and we could use some work on dominating personalities.

But one things I loved to observe on the more quiet ones. They aced listening and it showed up as timely contributions when no one else knew where to head right now.

Oh Style

The group ended up on one computer with one IDE in the morning and another computer with another IDE in the afternoon. Keyboard shortcuts would fly around, and made different IDEs obvious.

On the order of doing things, there was more disagreement than we could experience and go through in one day. Strong opinions of "my way is the best way" would be best resolved doing similar tasks in different ways, and then having a retrospective discussion of the shared experiences.

And observing the group clean up code to be ready to check in was enchanting. It was enlightening to look at group who have "common rules" to not have common rules after all. Mobbing would really help out figuring the code styles over the discussions around pull requests.




Thursday, March 9, 2017

A Simple Superpower

There was a problem and I could tell by the discussions in the hallways. I would hear from one side that the test automation doesn't work, and it will be perhaps fixed later - but uncertain. And I would hear from the other side that there's a lot to do, with suspects of not really having time to address anything outside immediate attention.


I don't have a solution any more than anyone else. But I seem to have something of a superpower: I walk the right people into one space to have a discussion around it. And while the discussion is ongoing, I paraphrase what has been said to check if I heard right. I ask questions, and make sure quiet does not get interpreted as agreement.

There's magic in (smart) people getting together to solve things. But seems that bringing people together sometimes is a simple superpower. Dare to take room for face to face communication. If two is enough to address something, great. But recognizing when three is not a crowd seems to provide a lot of benefits.

If you can use 15 minutes in complaining and uncertainty, how about walking around to have a practical solution-driven discussion. It's only out of our reach is we choose so.

Tuesday, March 7, 2017

Testing in a multi-team setting

There's a lovely theory of feature teams - groups of people working well together, picking up an end-to-end feature, working on a shared code base and as the feature is done (as in done done done as many times done as you can imagine) there's the feature and tests to make sure things stay as they were left off .

Add multiple teams, and the lovely theory starts shaking. But add multiple teams over multiple business lines, and the shakiness is more visible.

Experiencing this as a tester makes it obvious. I work on one business line and the other business line is adding all these amazing features. If the added feature was also built and tested from my business line's perspective, it would be ideal.

The ideal breaks on a few things:
  • lack of awareness of what the other business line is expecting and needing, and in particular, that some of the stuff (unknown unknowns) tend to only be found when exploratory testing
  • lack of skill on exploratory testing to do anything beyond "requirements" or "story"
  • team level preference to create test automation code only to match whatever features they are adding
I've been looking at what I do and I'm starting to see a pattern in how I think differently than most people (read: programmers) in my team. When I look at the work, I see two rough boxes. There's the feedback that I provide for the lovely programmers in my team (testing our changes / components) and there's the feedback I provide for the delightful programmers in other teams (testing their changes in product / system context).

It would be so much easier if in the team everyone shared a scope, but this division of "I test our stuff and other teams' stuff" gets very clearly distinguished when seeking for someone to fix what I found. And I find myself running around the hallways meeting people from the other teams, feeling lucky if my feedback was timely and thus a fix will emerge immediately. More often than not, it isn't timely and I get to enjoy managing a very traditional bug backlog.

Features teams that can and do think in scope of systems (over product lines) would help. But in a complex world, getting all the information together may be somewhat of a challenge.

Minimum requirement though: the test automation should be timely and thus available for whatever the team is that is now making (potentially breaking) changes without a human messenger in the chain. 

Thursday, March 2, 2017

The Awesome Flatness of Teams

For a long time, I've known that benchmarking our practices with other companies is a great way of mutual learning. But a lot of times these benchmarks teach me things that I never anticipated. Today was one of these and I wanted to share a little story.

Today, I found myself sitting on Skype facing three people just as agreed. One of the three introduced themselves as "just a quality engineer", whereas the others had more flashy titles. I also introduced as "just a quality engineer". Turns out those words have fascinated me since.

The discussion lead me to realize I have yet really not given much credit to how different from most places out team structure is. Our teams consist of people hired as "software engineers" and "quality engineers" and there's somewhat of a history and rule of thumb on how many of each type you would look for in a team. We share the same managers.

When you grow in a technical role, you move to senior, lead and principal in the same family of roles. And usually the growing means changes in the scope of what you contribute on, still as "just a member of a team".

As a lead quality engineer, I'm not a manager. I'm a member of a team, where I test with my team and help us build forward our abilities to test. With seniority, I work a lot cross-team figuring out how my team could help others improve and improve itself. I volunteer to take tasks that drive our future to a better state. I'm aware of what my team's immediate short term goal is, but also look into finding my contribution to the organization's long term goals.

Our teams have no scrum masters. The product owners work on priorities, clarifications and are a lovely collaborator for our teams. I'm not allocated a technical (quality engineering) leadership, I just step up to it. Just like the fellows next to me.

So I'm "just a tester", as much as anyone ever is just anything. But much of my power comes from the fact that there's no one who is anything more. Everyone steps up. And it's kind of amazing. 

Wednesday, March 1, 2017

Seeing symmetry and consistency

Morning at office starts off with news of relevant discussions that took place while I was gone. So I find myself standing next to a whiteboard, with a messy picture of scribbled boxes, arrows, acronyms. And naturally none of it would make sense without a guide.

But with a guide, I quickly pick up what this is about. A new box is introduced. Number of arrows is minimized. The new box has new technology, and I ask some questions to compare and contrast that to the other technologies we're using to figure out if there's a risk I'd raise right now.

I also see symmetry. There's boxes for similar yet different purposes. Pointing out the symmetry as a thing that makes sense from testing perspective (I know what to test on the new thing, as it is symmetrical to the old thing) gets approving nods.

I end up not raising up risks, but complimenting the choices for symmetry and choices of leaving boxes without changes that I was expecting they might be changing simultaneously just because we can.

There's hope for incremental development.