Bootstrap1 has been around for a number of years now. Open sourced by Twitter, its popularity grew so fast that it inspired a bit of reaction.2 And not without reason. Numerous websites took the bootstrap framework and slapped it on like the latest fashion trend. The result being a certain sense of sameness across the web. It’s only been five years, but it certainly seems like it has been around a lot longer than that. And bootstrap is still spreading out there. It’s added some new tricks during that time, and people are still pointing out the sameness spreading across more sites.3
And while I agree the public facing image of any business should be expressive of that company, I love to use Bootstrap. I am not a designer. I don’t think in CSS, except when I am trying to create Selenium locators. I also don’t build stuff that is the public face of any business. I make tools that are used by a limited set of people, and sometimes it’s just me. So originality in web design isn’t where I should be spending my efforts
Over the years I’ve used Bootstrap in a few places, and to good effect. My first use was to provide some new theming options to FitNesse4. They weren’t mandatory, but FitNesse was getting a bit dull and needed to get freshened up. And as a user, I found that classic side menu poor UI, so implementing a navbar that didn’t scroll out of site, made FitNesse easier to use. Bootstrap was easy to incorporate and it really did improve the experience (well, at least I thought so).
More recently I’ve been building tools for my own use and the team I work with. The first one was a tool that automated several queries and interactions with our test databases. I wrote the one in Sinatra5, another of my favorite tools, and incorporating bootstrap gave me a clean design that let me focus on getting the database and REST calls working. The second project, is a tool for benchmarking certain parts of our application and watching for big slowdowns. I’m currently building this tool in Wicket, as I don’t already know a Java-based web framework. And since I needed something to clean up the look of my HTML, I found and employed Wicket-Bootstrap6. Turning to Bootstrap again let me focus on learning how to build pages and interact with Wicket components rather than tweaking the cell-padding and other style attributes to get something I liked. Is it going to win a design award, no. But it will be functional and not super-ugly.
So, while I know that this causes a sense of “sameness” in the designs of these tools, using Bootstrap let’s me focus on what I need to do, which is build the tool. No one is employing me for my web design skills. We have excellent people at my company to do that, and they don’t need to spend their time styling a tool that will only be seen by internal employees. It may be a bit played out in the greater world wide web, but I’ll stick with bootstrap as a way to build tools faster with some decent styling.
Not everyone needs to build web-based tools in their day to day jobs. At one point I probably would have built tools like this in Visual Basic. I still write ruby scripts to automate tasks. Seriously, I even wrote some Perl recently. The point being, use the tool/mechanism that makes the most sense for what you need. And if you have to build a front end on your tool, don’t feel like you have to conquer styling it all from scratch. Swing by the getting started page for Bootstrap and figure out how to add it to your little web-based tool. Who cares if it looks a lot like twitter or a hundred other sites. It’s for you and your team, and it just needs to work.
Just thought I would drop a note. Last year I posted about my health1 and then I went silent on this site for quite a while.
First off, I’m doing fine. I continue to be in remission with the Myeloma numbers looking great. Additionally, the regular blood work I have done shows that my other blood cells and my immune system are stable. Maybe on the low side for most people, but nothing to be concerned about.
This means I’ve been fortunate to be working full time (minus the occasional trip to the clinic for the infusion of a bone strengthener). My job remains challenging and interesting. I’ve continued my work with Cucumber2 and grown our suite of tests nicely. Along the way I’ve improved the infrastructure of our setup and while we have fewer tests/checks running than in the old approach, these tests are more stable and a lot easier to diagnose.
Due to the focus I have on automation, I’ve been doing less testing of features, though I still do some. Mostly I mix my time with monitoring the bug queue from the customer. This has me investigating a wide range of things. One of the highlights of that process has been the opportunity to grow my knowledge of the code and diagnose or answer some questions w/o a developer.
I’ve also started a new project to build a framework for benchmarking certain parts of the system. It’s a very simple tool, it just allows for us to create short scripts and then send the timings or other values identified by the scripts into a database and then report on when the timing or value falls outside an expected range. My research didn’t find anything like what I needed available, so I’m building it out. It’s also an opportunity to learn Wicket,3 the web development framework we use.
So, I’m still here and I’m still kicking. And I’m still learning and growing.
It’s really Java intensive. I guess I might have preferred something else, but there is a lot in it that I don’t have to do myself. And, since it is what our product is written in, it gives me a better understanding of what is possible and where things can fail. ↩
I’ve been on Squarespace for quite some time now, but I’ve been reluctant to move to their newer versions. Considering how little I was posting, it wasn’t worth paying more each month for that. There are some pretty nice tools and features on there, but really, I wasn’t using them.
Additionally, the iOS experience for Squarespace was pretty mediocre. Especially if you haven’t upgraded your site. The apps, when they worked, they were pretty poor. And the support for markdown was less than ideal.
Moving to Jekyll brings with it a number of benefits:
- It’s pure markdown, so it works more the way I want it to.
- There are lots of themes available and the majority of them are already responsive (like this one).
- It supports nice code formatting for examples.
- github provides a way to host it that doesn’t cost any extra
- The content is much easier to control, since i have a copy of it locally in addition to living in github.
We’ll see how often I post. I’m thinking that this blog is going to expand a bit in scope. I do a little less testing and a bit more automation and development.
So, I have cancer. It’s a rare blood cancer called Multiple Myeloma. I was diagnosed back in December and quickly started induction chemo. Before I get too far into this, things are going well. The treatments have beaten down the cancer and I’m feeling OK.
Throughout the treatment process I’ve had lots of tests done: bone surveys, MRIs, PET scans, bone marrow biopsies, blood work, and more. MRIs, X-Rays and PET scans are all very interpretive in nature. There are numbers and measurements (such as the size of a tumor), but they are visual in nature and not as easy to get a handle on and may even require special software to view.
So along the way, well I made a couple of mistakes that I shouldn’t have as a tester.
Mistake Number One: I Didn’t Confirm What Was Important to the Stakeholders
Blood work is all about the numbers. I can’t speak to the process for any other cancer, but treating and managing Multiple Myeloma (MM) is a lot about numbers. Lots of numbers. And going into things, I had no real idea what numbers mattered. Well, all the numbers matter, but only certain numbers matter when it comes to the cancer itself. Others are secondary, but related. And then more just are there because they help identify other problems that might exist in the system (also known as my body).
Now being a tester and a former QA/metrics guy, I started to explore the numbers to figure out what they mean. And when I started, I had no idea what the meaningful numbers were. On the typical week, I had enough blood drawn to generate a page full of results. And some weeks, there was a bunch more. Early on I was tempted to, but decided not to chart how many vials of blood they took (the high in one sitting was 12).
Unfortunately, I didn’t press the doctors (SMEs) from the start on what the numbers all meant. I got clues early on about some of them, but I didn’t seek clarification. Some of them I knew from a layperson’s perspective (white blood cell count, red cell count, platelets were all names I recognized). After a while I picked up some more, such as they were interested in my Absolute Neutrophils (which I learned are essential to fighting off bacterial and fungal infections). It turned out that this was a really important number to know about, as I was Neutropenic in late December when I suffered from Tumor Lysis and needed to be extra careful.
Over time I learned more. From MM podcasts and MM forums came the all important “M-Spike”. I realized, I didn’t know where or what mine was. When I was in the office, it was mentioned as important for getting Myeloma under control (it should be zero), but we didn’t confirm where to find it in my labs. Eventually some internet research paid off and I knew more about what the M-Spike was - an unusual concentration of monoclonal proteins based off of a specific source - then I was able to examine my various test results and find the value. The process of identifying the M-Spike involves interpretation by a pathologist, so it isn’t automatically collected and inserted into a numerical field. Instead it is part of a longer text field that explains the data. This also meant that MyChart by Epic Systems can’t treat it like numeric data and generate graphs of it changing (more on that later).
On a completely unrelated note, you can be come a Non-Secretor. This means that you have Myeloma and the cancer is growing inside you, but the version you have has decided to stop creating the monoclonal proteins that make it noticeable. Then blood work isn’t as useful and you need more PET scans.
There are other numbers that I found out were directly related to Myeloma and others were indirectly significant. Directly related is a thing called Free Light Chains and the Free Light Chain Ratio. These are building blocks of antibodies that get out of whack due to the bad Plasma cells created by Myeloma. There is a range that these numbers should be in and there is a ratio between the two that is normal. You pretty much want your M-Spike gone AND your kappa and lambda light chains in balance. If I was going to play with analogies, M-Spike and Light Chain Ratio are a combination of direct bug reports and related issues in your system, you want them to be zero or at least under control.
Those indirectly related numbers. Well those are your normal blood cells, neutrophils, uric acid, LDH, albumin, calcium and other blood chemicals and cells. The normal blood cells get suppressed by the overgrowth of Myeloma cells. This leads to anemia and immune system weakness. Other blood chemicals can get out of balance due to cells being killed by the treatment. The doctors monitor all of these numbers so they can respond with treatments to correct when things get out of alignment. My weak analogy here is that the indirect numbers are a bit like the performance metrics (memory, cpu, disk access) for the system including your software.
Now I’m not the tester in this situation, but I’m a key stakeholder along with my treatment team. How often is it that a key stakeholder doesn’t really know what is going to deliver value? Well, more often than what you would guess. Thinking like a tester though, what I should have done is taken more time to ask what the numbers meant and what we wanted to see in the long run.
Mistake Number Two: Taking a Single Sample as an Absolute Truth
As I learned more about the numbers, I started asking about more of the tests. Eventually, I learned more about the results of my Bone Marrow Biopsy. The initial one found a lot of Myeloma. Additionally, they found that Myeloma cells were free floating in the blood, which isn’t normal. Apparently they were pushed out into the blood from the very full marrow.
At the conclusion of induction chemo (treatment to knock down the Myeloma and prepare me for a stem cell transplant), we did another biopsy. The second biopsy was done in the same hip as the first time. A few days later, When I got the call from my nurse practitioner and she said that they found no sign of Myeloma in my bone marrow. Well, I got excited, and I told my family about it, and everyone was very happy for me.
Well, as a tester, I should have remembered that this was one data point. Before you freak out, it’s not bad news. Just not as good as what I initially latched on to. A couple weeks later I had to go in for more tests and that is when I realized that my M-Spike was not zero, but 0.35. I started at 4.06, so that is still a huge drop. In Myeloma terminology it’s called a Very Good Partial Response and its the best that some patients get.
Later, a second PET scan showed no active clusters of Myeloma in my bones. This being another very positive result. Just like the clean bone marrow biopsy, and a low M-Spike, this points towards a system that has been brought under control. Taken by itself, it would still be insufficient, but in combination with the blood work, skeletal survey and biopsy, it does indicate a strong success. So I’ve still got some of those bad cells out there, just a lot less an not clustered in big groups. But that’s OK.
But lesson learned. As a tester I should know better than to take one good result as gospel. Think about it. A single sample in one location can miss an important find somewhere else. This is why we don’t rely on a single test or a single approach in software testing. We know that there could be bugs hiding next to the spot that just worked for us. And we also always know that even with our best efforts, we are not going to find every bug in the software. We need enough testing and enough data to establish the risk in releasing.
Not Mistakes, But Applications of the Tester Mindset When You Have a
So a few thoughts I’ve had about things that a tester mindset can do for you when you have a medical condition.
Don’t Be Afraid to Question Things
Only one person has a single-minded focus on your case, and that is you. The doctors and nurses are treating lots of people. They are professionals and should be doing all of the right things. Sometimes though, things happen. If someone is going to give you a treatment you don’t think sounds right, ask about it. Be assertive. It never happened to me that I was going to get the wrong drug, but people on the forums have.
Remember, as a tester, it is your job to notify people of inconsistencies and risks. The stakes just aren’t usually so high or so personal.
Just as a tester needs to communicate with their team, a patient needs to communicate with their doctor. The blood work, scans and X-Rays can only tell them so much. You as the patient need to communicate how you feel and how the treatments are affecting you. Quality of life is important and sometimes changes are needed.
Leverage the Tools Available To You
I have never been given a testing tool that did what I wanted out of the box. And the MyChart system from Epic, while pretty decent, is no exception. I’ve created my own spreadsheets to track the numbers, including the all important M-Spike. I’ve hooked up this crazy combination of a symptoms recorder in Workflow triggered by Launch Center Pro and that uses Launch Center Pro to send data. To Evernote and to a Google spreadsheet via IFTTT. So I’ve built my own dashboard and metrics tools to track things the way they make sense to me.
Point there, is taking care of testing or tracking your health, leverage the tools you like and are comfortable with. You don’t have to take stock options and limit yourself there.
Learning you have cancer and quickly starting cancer treatment is not the same thing as testing insurance software or the next big app. In those initial days, I was focused on the prognosis, which thankfully was a lot better than the median survival rates that are published (based on older data). And then absorbing the fact that I was starting chemo in a week, and then learning to adjust to the ups and downs and of chemotherapy. Unless you are in the medical field, or have had to help a friend or a loved one though this, it’s probably all new to you. It certainly was new to me. And it’s not like we didn’t ask a lot of questions. We asked a ton, but how we were going to measure and track the treatment wasn’t one of them.
So it took a little bit, but now I have a better understanding of what is going on. I understand more about the myriad of numbers that come from the blood draws. As this is a new domain to me, I still have tons to learn. I’ve got a good team working on things, and I expect to have plenty of time to learn more.
And some remaining thoughts. First off, I don’t intend to make this into a cancer journey blog. I deeply respect the people who have public blogs for that purpose, but that is not for me and this is not the place. We might see some more thoughts about the intersection of testing and my experiences, but I doubt there will be many. Second, I am doing well. It hasn’t been easy, but it could be a lot worse. Finally, I am immensely grateful for the support my family, friends, coworkers, neighbors, and employers have given me and continue to give me. I’m a lucky man.
I’ve recently started a conversion of Junit-style Selenium tests to using Cucumber. The goal of this is not currently BDD, but more about writing example driven tests that will focus on the significant behaviors in the system. But I’ll save my thoughts on the test authoring style for another day.Today I want to talk about my experiences converting the existing framework from being heavily singleton based to using Dependency Injection using Weld.
The Pragmatic Programmers just recently released The Cucumber for Java Book which I have been following since the beta book was announced. It’s a very useful book if you are a tester/programmer in the Java world and are interested in using Cucumber. As an aside, I do in principle agree with Adamin his recent post that you don’t have to write your tests in the same language as your developers, but in my case, I have a large number of Page Objects that I can reuse, and we use QueryDSL to generate database objects for interacting with the database of the system under test. So if you are like me, and you feel Java is the best choice to write your tests, I highly recommend this book.
I’ve been aware of Dependency Injection (DI) for quite some time, but have not really used any frameworks for it in any of my previous testing automation.But I was very intrigued by the chapter in the book that covered using various DI frameworks in Cucumber and that Cucumber is essentially DI aware. Having no personal opinion on on the available frameworks, I chose Weld, as that is what our developers use. Again, is is not required to use the same framework as your developers, if you are not directly using their code. In my case, I chose Weld because they do use it and are very willing to help with questions. Given the choice between learning on my own or leveraging their knowledge, I chose to leverage.
Challenge Number One: Becoming Pojos
Weld requires that the objects you are using be Pojos, or Plain Old Java Objects. This means that all classes should have a constructor, with no arguments, or a constructor that takes a single argument where that argument is another injectable object.This meant architectural changes to the WebDriver wrapper, the logger, the database objects and the page objects. All of these needed to be changed to make Weld happy with them.
In principle this wasn’t too hard to do, but it took some discovery to find the various changes I needed. And even then, it required some additional trial and error (and help from my developer) to identify classes that were created using public fields rather than setters and getters. Weld is rather opinionated about class design, and that’s OK. I just had to get used to identifying where our code didn’t match what it wanted.
Typical changes I made included:
- Making sure that instead of executing code in constructors, used @PostConstuct annotated methods. Weld injects objects after the constructor is called, so you wind up with NullPointerExceptions if you use injected fields in the constructor.
- Converting public fields to private ones with setters and getters
- Changing the page objects to skip validation steps that used to happen in the constructors, as the page objects are injected now. This means that the pages might not be active/visible when the constructor (and @PostConstruct methods) are called.
- Converting some utility classes that were written using static methods to be injectable Pojos instead, as they needed other classes injected into them (and figuring a way around the circular dependency I created at one point).
These changes turned out to be reasonable, it just took a little bit of education and effort to think through. I’m liking the result. I haven’t had much issue with the code once I figured my way around the places where it didn’t match what Weld expected.
Challenge Number Two: Dealing With a Little Classpath Hell
Back in the old days of Windows development, we all had to deal with the special joy known as DLL Hell. Back then you had C and C++ based libraries that might have the same name, but have different entry points and software would crash when you called a version of a method that was different orc hanged in the version of the DLL found by the application.
Well the Java version is Classpath Hell. Where you have different versions ofJars being used by the various Jars you are dependent on. Java is better about this than the DLLs of old, but you can still get caught. I was initially usingWeld-SE 1.1.0 as the version of Weld in my pom file. But when I tried to run,I would get a MethodNotFoundException because the version of google collections I was getting didn’t have a method that an updated version ofSelenium wanted. I went through all of the dependency tree and tried doing exclusions of guava from other jars with no success. Eventually my developer(who was extremely helpful every time I needed him) dug all the way into theWeld jar and we discovered that they had actually incorporated the google collections code into their code and didn’t rename the packages. The result was that their version of the code was always being found. The fix was a newer version of Weld, but it was a bunch of headaches to get there.
Challenge Number Three: Learning the Quirks of Cucumber Lifecycle
Cucumber is very well thought out. I really appreciate the separation of concerns between Feature doc, Step Definitions, Helper Code and the WebDriver.It makes for a great structure. It also enforces some rules and behaviors that were different than I expected. And some of these quirks had a relationship to how Cucumber worked with Dependency Injection. That isn’t bad, but it still requires learning and then adapting.
A couple of key things I learned:
- @ApplicationScoped classes are potentially recreated on for each test. You may still need a Singleton to ensure that you get a single browserDriver created for the test run.
- On a related note, I created SharedTestData class to carry data between step definition files. This worked well enough, until I tried to use it in a @Before and @After hooks. The SharedTestData was reset when the test ran, so values stored in the @Before didn’t make it to the @After. Created a separate SharedHooksData to carry data between hook files.
There are still challenges waiting for me out there. I’ve just really started working through converting all of the page objects and creating the new tests.I’ve got a good start going and I feel like I’ve broken through the initial barriers. But I know that there will still be some behaviors I don’t expect inCucumber and with Weld. I’m better able to handle them now than when I started. It doesn’t mean there won’t be some cursing and some frustration, butI’m up for the challenge. I’ll come back and document the other challenges later.