Showing posts with label qa basics. Show all posts
Showing posts with label qa basics. Show all posts

Sunday, July 19, 2020

Language: Precision vs Accuracy


Motivation

People conflate these words but they are distinct, and I think the distinction is both useful and kind of cool.

In short:

Precision: the degree of refinement with which an operation is performed or a measurement is stated
Accuracy: correctness

Precision has to do with specificity, not necessarily correctness.  Accuracy is all about correctness.

Example 1:

If I said 1 foot is 492.763 millimeters, I would have given you a very precise but inaccurate number.
If I said 1 foot is about 300 millimeters, I would have given you an imprecise, but reasonably accurate approximation.
If I said 1 foot is 304.8 millimeters, I would have given you a precise and accurate number.

Example 2:

If I said the Texas State Capitol building was at latitude/longitude 30.276930, -97.7441325 I have given you a very precise location, but it's not accurate.  It's not correct.  In fact, it's cosmetic surgeon's office.  Notice the red pin in the upper-left:


If I said the Texas State Capitol building was at latitude/longitude 30.275, -97.74 I have given you an accurate location, but the GPS coordinates are of low precision, having only a couple of digits after the decimal place.


If I said the Texas State Capitol building was at latitude/longitude 30.2746742, -97.740345 I have given you accurate, highly precise coordinates for the center of the capitol rotunda.  If you sing in there, it sounds REALLY cool.  It's virtually all marble and granite, so the acoustics are incredible!



Wednesday, March 6, 2019

Language: Necessary and Sufficient

Motivation


This is a nice piece of language I learned in school long, long ago.  It's very useful when talking about requirements or specifications for a project, acceptance criteria for a user story, etc.  Bonus: it makes you sound smart.

Example


The long and short of it is that what you want in order to work efficiently and effectively is the necessary and sufficient information (or tools or whatever).  Since I like working on cars, I'll use the simple example of changing a tire.

If you have the following, you have the necessary and sufficient toolset:
  • a new tire
  • a lug wrench
  • a car jack

If you have the following, you have tools that are necessary, but not sufficient:
  • a new tire

If you have the following, you have tools that are sufficient, but not necessary:
  • a new tire
  • a lug wrench
  • a car jack
  • a hammer

If you have the following, you have tools that are not necessary, and not sufficient:
  • a hammer

Recap


Necessary defines the lower bounds of what you need while sufficient defines the upper bounds.  If you have both, you have the ability to do the work completely while being perfectly efficient.

Sunday, December 30, 2018

Information Science: What do Digital and Analog Mean? It's Fairly Simple Really...

Motivation

People frequently use the word "digital" to describe anything that's modern.  It means something specific, and it's pretty easy to learn.  And learning is cooool.

"Digital"

In modern society, "digital" is often used in non-scientific ways from "digital music" to vague sentiments like "the Digital Age."  Digital and analog have simple meanings, and neither has anything to do with computers.  Digital simply means you're using a set of values that you know the exact values of.  In computers, that set of values is 0 and 1.  It is a discrete set of values.

"Analog"

Analog simply means you're using the full, continuous range all values between your minimum and maximum.  There are an infinite number of values between 0 and 1.  For example, 0.5 and 0.6.  But I can "go between" these numbers with the value 0.55.  and I can "go between" 0.55 and 0.6 with 0.575.  I can keep doing this infinitely.  Analog systems do not measure, track or store discrete values.

Examples

The simplest example of this I can think of involves musical instruments.

Imagine a trombone: you can play an E by holding the slide in a certain position.  To play an F, you move the slide a little closer in, but if you move it a little less than you should, you're between the two notes.  Since you're not playing an E or an F, it's probably going to sound bad because you'll be flat.  You can play an E and an F, but you can also play the full, infinite range of pitches between those 2 notes.

On piano however, you press the E key, you get an E, you press the F, you get an F.  You cannot play the pitches between those notes.  That's nice because it's one less thing to worry about... but you also can't play the "womp womp" sound.

The trombone is analog and the piano is digital.

A few more quick examples are a full-on rainbow, versus a simple rainbow:


And slider belt versus a belt with holes:

The Physical Medium vs How It's Used

In the case of the belts above, you might notice something: The "digital" belt with the holes cannot be used in an "analog" way.  The "analog" belt however... if you used white paint to make lines on it every inch or so, and you chose to only use the belt at those increments, you would effectively be using the "analog" slider belt in a "digital" way.  In fact this is true of cassette tapes (think 1980s).  Cassette tapes were primarily used to store music, for example MC Hammer's "Too Legit to Quit," but they were also used in computer systems (Atari, Commodore, etc.) to store binary (digital) data.

I used them some in the 80s and was surprised how well they worked.  I'm guessing the error rates on these tapes wasn't too bad because with binary data, only having 2 values to represent meant you could make it pretty clear which was which.  It wasn't like playing an E versus an F on a piano (most humans couldn't tell you which was which) it was probably more like playing the very lowest note on a piano versus the very highest (most humans could easily tell you which was which).

Digital as "Better"

The reason people think of digital as better than analog is because you can make a perfect copy of it.  A cassette tape with music on it is analog.  If you recall, every time you made a copy of one, the quality deteriorated a little.  If you made a copy of your friend's tape, then another friend made a copy of your copy, it sounded noticeably worse than the original.  An analogy for modern times might be if you take a picture with your phone, and then someone takes a picture of your phone's screen, and then someone else takes a picture of their phone's screen.  That 3rd picture's not going to look too good.

If you made copies with a low quality tape recorder vs a higher quality one, it made a difference.  It might even make a difference if you made the copy in a room that was really hot or humid.  This is because the data on the tape was analog, and the tape recorder reading that tape is not precise enough to read the data exactly.  In the same way, while the best trombone player in the world is very very close to hitting that E on their instrument, their finger placement will probably actually be sharp or flat by at least a nanometer or two...

However, if you make a copy of a music CD, you can make a copy of that copy, and a copy of that copy, etc. and it will be an exact copy of the original.  The original and all of the copies are perfectly identical.  The modern analogy would of course be just emailing the picture to your friend so that they have a copy.

Why We Care

Basically, it's simply much easier to make an exact copy of something that is stored using discrete values.  For computers to execute computer programs exactly the same way every time, digital is the way to go.  Most of the time, when a program crashes or doesn't do what you want, it's not running it wrong.  It's running the program - with all of its bugs - exactly as it was written.

Friday, December 28, 2018

Information Science: Information is Meaningless Without Context - Now With Puppies!

Motivation


Most simple text editors will open any file and try to display it as text.  This phenomenon is where this post came from... a junior coworker asked why an .exe looks like garbled text when viewed with a text editor.

The answer is context.

What does "10110101101000101110101110" mean?  


Well it depends on who you ask.
Let's put those exact bits into a file called:
  • my_file.jpeg and open it with Photoshop - it's going to be interpreted as an image
  • my_file.mp3 and open it with iTunes - it's going to be interpreted as sound
  • my_file.txt and open it with Notepad - it's going to be interpreted as text

That's oversimplifying it because some standard file types such as jpegs and mp3s must always start with a "header" that basically says "this is an mp3," but let's ignore that for a moment.  Let's just talk about the 1s and 0s that represent the song in the mp3 file.

How many puppies does "11" represent - A, B, or C?

A


B


C

The answer again is context.
  • If "11" is read as decimal (base 10, which we all use in everyday life), then it's A.
  • If "11" is read as binary (base 2), then it's B.
  • If "11" is read as octal (base 8), then it's C.

For a quick read on this, see Information Science - A Simple Explanation of Base Number Systems: Binary, Decimal, Octal, Hexadecimal

So when a program like iTunes sees a string of 1s and 0s it's going to read it as sound, and if it's just a random string of 1s and 0s, it'll be pretty noisy.  An .exe file is supposed to be read by the operating system, so if you open it with a text editor it tries to turn the 1s and 0s into a bunch of letters, so it just looks like garbled text.

Other examples

Human Languages

To think of this yet another way, I could write "Plato" on a piece of paper and give it to someone who speaks English and they'd probably interpret it as the name of the Greek philosopher.  If I give that same piece of paper to someone who speaks Spanish, they'd probably interpret it as a flat round thing you eat food off of ("plato" is Spanish for the English word "plate").

Character encoding schemes

Similarly to the decimal vs binary example, we have different standards that make a specific set of bits represent different readable symbols.  Some examples you may have heard of are ASCII and ANSI.  Let's take this set of bits:
01001000 01000101 01011001 00100001

ASCII was thought of long ago as a simple character set with a small range of 00000000 to 11111111 (a total of 255 unique characters), so each of the 4 chunks above represent a character... in fact it represents "HEY!"

Unicode is intended to be the last character set we'll ever need, so it has a huge range of 1,114,112 unique characters, currently only around 100,000 of which are used.  It's a much more complex system, including the Latin, Greek, Cyrillic, Chinese, and Thai alphabets (along with others) and all kinds of symbols for music, math, just about anything you can think of.  Suffice to say, if you give a long string of 1s and 0s, interpreting it as ASCII and Unicode will likely not yield the same result.

To sum up...


and reiterate (to a hopefully tediously clear degree): information in a file is just like information in the real world - it can only be correctly understood if the context is correctly understood first.

Information Science - A Simple Explanation of Base Number Systems: Binary, Decimal, Octal, Hexadecimal

Motivation


I Googled for a quick, simple explanation of this and was very surprised when I failed to find one, so here we go.  Oh, and the whole puppies thing is a reference to this post.

Bases


The base is just defined by how many characters we have to represent numbers.
  • In binary (base two), we use characters 0, 1
  • In octal (base eight), we use characters 0, 1, 2, 3, 4, 5, 6, 7
  • In decimal (base ten), we use characters 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
  • In hexadecimal (base sixteen), we use characters 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F
In decimal we can represent zero to nine puppies using only one character.  At that point if we add another puppy, we have to move over a spot and start over with the one character, so we count:
  • zero 00
  • one 01
  • two 02
  • three 03
  • four 04
  • five 05
  • six 06
  • seven 07
  • eight 08
  • nine 09
  • ten 10  --  here we start reusing characters...
  • eleven 11
  • twelve 12

but for binary we only have two characters with which to represent puppies, so we have to move over a lot quicker:
  • zero 000
  • one 001
  • two 010  --  quickly we start reusing characters...
  • three 011
  • four 100
  • five 101
  • six 110

similarly for octal, we count:
  • zero 00
  • one 01
  • two 02
  • three 03
  • four 04
  • five 05
  • six 06
  • seven 07
  • eight 10  --  here we start reusing characters...
  • nine 11
  • ten 12

and finally, for hexadecimal, we have to "make up" some extra characters that we're not used to (since most humans are used to the decimal, or base 10, system), so someone long ago chose the letters A-F:
  • zero 00
  • one 01
  • two 02
  • three 03
  • four 04
  • five 05
  • six 06
  • seven 07
  • eight 08
  • nine 09
  • ten 0A
  • eleven 0B
  • twelve 0C
  • thirteen 0D
  • fourteen 0E
  • fifteen 0F
  • sixteen 10  --  finally we start reusing characters...
  • seventeen 11
  • eighteen 12

Hexadecimal can be a little weird to think about but try thinking about it this way:  if someone created five hundred unique characters that we used to count things, we could just point to a herd of, for example, four hundred and eighty puppies in a park, and you could use a single character to represent that number. That character would uniquely identify the number of puppies you see sniffing and playing and rolling in the dirt.  My guess is that you would spontaneously explode from how cute it was.

A generic formula for figuring out what a number means in your base


So the generic formula for figuring out how many puppies we're talking about is to take the base multiplied by itself the number of times we've had to "move over a spot" and then multiply it by the number in that spot.

So "432" in decimal:
  • ten * ten * four +
  • ten * three +
  • two =
  • Four hundred and thirty two

"432" Octal:
  • eight * eight * four +
  • eight * three +
  • two =
  • Two hundred and eighty two

"2BC" Hex:
  • sixteen * sixteen * two +
  • sixteen * eleven +
  • twelve =
  • Seven hundred

"1101" Binary:
  • two * two * two * one +
  • two * two * one  +
  • two * zero +
  • one =
  • Thirteen

The formula can also be expressed as "the base raised to the power of the number of times you've had to "move over a spot."  It's just the same.  For example:

"432" in decimal:
  • ten to the second power * four +
  • ten to the first power * three +
  • ten to the zeroth power * two =
  • Four hundred and thirty two

Monday, November 26, 2018

Automation Strategy (Email): We Will Achieve Efficiency Through Correctness, Not Speed

I just thought this was important enough to make a post about.  At first I thought it would be self-explanatory, but in case it isn't - I'm talking about team efficiency, not processor efficiency, although the case could be made there as well.

This is a team of contractors who, like most contractors, wanted to pump out tests and executions.  I consistently ask them to slow down and write good code so that our pull requests go faster and our code requires less debugging during automation execution.



From: JW

Date: Monday, November 26, 2018 at 1:20 PM

To: AP, VG

Subject: Re: Test_Automation(22-Nov-2018)


Team,
Please always pay attention to details.  Our Pull Request numbers and SQA Project numbers are very close.  Below it says PR 475 but should be SQA-475.  Not a big deal, but just go a little slower - we will become the most efficient by prioritizing correctness over speed.  The same is true for writing clear, understandable code.  We need to think more about the next developer than we do about ourselves.  If it takes you extra time to save your teammate time, please do it - a week later you may be the one receiving this gift!


JW
Automation Lead



From: AP
Date: Thursday, November 22, 2018 at 10:45 AM
To: JW
Subject: Test_Automation(22-Nov-2018)

Hello Team,
As per plan of action, team worked on automated suite execution and failure analysis of 18.12 release.

AP:         
  • Worked on failure analysis of OR and fulfiller-15569 automated regression tests(SQA-469)
  • Updated the Wiki page for 11 known issues of 18.12 release. 
VG:
  • Reviewed PR 475 and updated comments in JIRA for it
  • Reviewed PR-419 and updated comments in JIRA for it
  • Created PR-423,PR-424 for SQA-453 and completed it

Tomorrow's plan of action:- To continue work on fixing the failed test-script and handling prescripts and further work on SQA board tickets.

Thanks!

Automation Strategy (Email): Method Naming - Do What You Promise

Team,
I have always made clear how critically important method names are.  Sometimes the difference is very big and sometimes is it more subtle.  I just want to point out a couple of examples I've just seen.

1.
A pretty big one is
verifyUserExistence()

which looks to see if a user exists, but if it does not, it creates a new user.  Creating a new user has NOTHING to do with verifying a user's existence.  I have created an issue to refactor the name to verifyOrCreateUser()


2.
adminViewFulfillerUsersPage.enterNewUserDetails()
I would expect this method to enter text fields on a page.  What it actually does is enter all the text fields, then click the Create User button.  This is a subtle difference, but in some refactoring, Vibhav renamed it to

adminViewFulfillerUsersPage.createAdminFulfillerUser()
which I believe is a better name, because this method does more than simply entering details.

Every time you write a new method, give serious thought to what its name should be.  The next developer to come along will waste a lot of time and be upset with you if your method says one thing but actually does another (or does more than what it says).  It would be like if you asked someone "Please get me a drink" and they said "No problem," then they got you a drink, drank all of it, and handed you an empty cup.  Don't be that guy!

Note that we didn't change the name from
enterNewUserDetails()
to 
enterNewUserDetailsAndClickCreateButton()

instead, we go up a level in abstraction and just called it
createAdminFulfillerUser()

This helps avoid creating methods with very long names.  If you have any questions or would like suggestions for method names, please ask.
Thanks-

Thursday, September 20, 2018

Automation Strategy: Externalize All Your Strings


Motivation

We need to externalize all the strings we use in our locators, such as "User order number" or validation methods, such as "Order Created."  Why?
  1. It'll make your code more maintainable if that string changes
  2. It keeps things organized
  3. Internationalization (i18n)
  4. Multi-platform automation
From the outset, you might as well plan for i18n by including a switch for locale (not language). Language is "English."   Locale is "American English" and looks like "en_US" or "en-US" depending on who you ask.  Google it.  I like to model the strings exactly as they are, including capitalization and punctuation:

This works well for automating small to medium apps that themselves maximize code reuse.  But for big (or legacy) applications it may not be the best approach due to non-standardization, your mileage may very.

And for multi-platform automation... (there is a lot more work involved, but this is part of the deal...)

Ok I'm going to be honest right now. I wrote the part above tonight and this next part 2 years ago and I don't even know what language this is. The filenames are .cs but I don't even know C# well enough to know if you can define methods like this, I might have just used .cs because gist colorization was good.  Hmm, now I'm thinking it's just pseudocode.

Anyway, the last thing I'll say about externalizing strings is about dynamic strings.
Here's option 1, strings live in the data file and you compose them in the page object class:

This is fine, but will require everyone who uses those strings to do all that string concatenation themselves, which is code duplication. It will also become a problem when the translation is weird. Maybe in American English we'd say "Order number 404 is on its way!" but in Canadian English they'd say "404 is the number of the order comin' at ya, eh!" If this were the case, our stringA + orderID + stringB wouldn't work, or would be wonky. Let's just write methods to generate those strings instead, and notice how it's used in the page class:

And you could even get really crazy and do kind of a mix, which lets you have both the individual strings as well as the pre-composed dynamic strings. It just depends on what you need for your situation:

Friday, March 30, 2018

Email: Git best practice - break up Pull Requests into smallish commits

Hi All,
We have talked about the size of commits, the size of PRs, etc. and here is an example where I’m creating a small/medium sized feature which touches a lot of parts of the code
  • environment data
  • test data
  • helper methods
  • extending existing classes
  • the test method itself

My goal here is to show an example of breaking a PR up into small, related commits so that it’s easier to code review.  The whole feature has to go in 1 PR because all the parts of this PR depends on all the other parts, and together it’s several hundred lines of code.  But if you look at the individual commits, it’s easier to see what I was trying to do.  I did an ok job with this but surely could have done better, especially the last commit, which is pretty big.

An important thing here is that just because you have changed lot of files or even if you have changed several parts of a single file, you do not have to commit everything you have changed.  Sourcetree makes it easy to “stage” files or parts of a file which will get committed when you call commit (for more on staging, see here).  This way, even if you have a lot of changes, you can still make commits that group related pieces of code together to make life easier for the code reviewer – and hopefully for all of us since the reviewer is more likely to catch any issues with your code.


Friday, June 23, 2017

QA Basics: How to Write a Defect Report

Generally, a bug/defect report should be self-contained and include all information required to reproduce and triage the bug.

Clarity and reproducibility are key.  The better bugs you write, the happier the devs will be.  Happy devs write happy code.  Happy code means less bugs!

The key components of a bug/defect report are:
  • Title
    • A concise summary, don't include reproduction steps (at some point you'll be tempted to)
  • Description
    • A discussion of what is wrong, possibly how it affects the user.  If you are familiar with the issue or the code, give that information.
    • If there is a history with this issue or this type of issue, include it here.
  • Environment
    • version or build #
    • platform or server
    • browser (Chrome, FireFox, etc.)
    • data such as user info (could also just be in Steps to Reproduce)
    • Can include other things (on mobile you could include things like connection type of WiFi or Cellular)
  • Steps to reproduce
  • Actual result
  • Expected result
  • Evidence
    • screenshots, logs, stack traces, etc.
    • for search ability: copy/paste key parts of logs, error msgs, and the top several lines of stack traces.  Screenshots of logs or err msgs are fine but ALSO paste the text in the description or a comment
  • Priority
    • How urgent should we fix this?
  • Severity
    • How severe are the consequences of this bug when it does happen?

I like to format my Steps to Reproduce as shown below, to allow for a discussion after each step (numbers = actions, dashes = how the app behaves).
Most companies don't have strict formats, this is just my personal style guide (just as dev teams have style guides for coding).

1.login to www.xyz.com as user01 password abcd1234
2.put any item > $100 in the cart
-cart shows the item but not the tax
3.go to settings page, then go back to the cart page
-cart now shows item AND the tax

I've included multiple actions in step 3.  Personally I think this is ok as long as it's unmistakably clear.

Priority vs severity:
See this post.

Tuesday, May 16, 2017

Email: The easy way to remember how to write a test plan

Team,
Something you’ll probably have to do at some point is to write a test plan.  There is an IEEE standard for writing test plans but no one follows it (maybe the military).  Test plans vary wildly from company to company.  Too small and it won’t be enough information, too big and no one will ever read it.

It can be hard to remember what goes in a test plan but it’s a common practice and interview question, so I think of it like this:
  • Who
    • Who are the stakeholders
      • Stakeholders can be loosely defined as “people with an interest in the project” such as project managers, product managers, key customers, your boss, etc.
      • If needed, write a RACI chart
    • Who will be doing the testing
      • Who is on the team, do we have enough people, do we have the right people
  • What
    • What will we test (what is the scope of testing)
      • Include a list of high-level areas we will test.  How specific you get will depend on the project. 
    • What will we NOT test
      • Include a list of what you will NOT test.  Sounds weird but this is very important to include.  This will include things like
      • the customer’s servers
      • security
  • When
    • Do we have a delivery date or a list of milestones (phases)?
    • If we need to deliver by date X, development must deliver to us by date Y
  • Where
    • Environmental factors
      • “we need a server with version 1.2 as well as version 1.4”
  • How
    • A discussion of tools we’ll use, testing types we’ll do (and maybe processes)
      • We’ll use the API
      • We’ll use Selenium
      • We’ll do load testing
      • We’ll test directly in the database
      • We’ll use processes X, Y, Z 
  • Why
    • …doesn’t really work in this who/what/when way of thinking

On top of all of this, a few things to include are

  • Risks
    • the dates are tight here, any shift in development will push us back
    • some environment goes down a lot or is out of our control (maybe it relies on the client or someone 3rd party)
  • Dependencies
    • we need credentials for X to complete testing
    • we need better specifications for Y part of the system
  • Results
    • How will you measure your success
    • How will you deliver that data