Follow Your Passion Or ............. Not

I read recently a few articles on what people should do to find success.

Some say "follow your passion", others "follow your effort", "do what contributes" or even "forget passion, forget goals".







Please see below the links to the original articles and some highlights.

In my case, FOLLOW YOUR EFFORT worked best.

But I consider Scott Adam's point of view equally important (WORK HARD, FAIL, TRY AGAIN).

Testing, my work passion, is not the first IT job that I had.

Over the years, I worked also as IT analyst & manager, software developer and web support manager.

The web support manager position was temporary by replacing someone who took maternity leave.

When that person came back to work, since the company did not have a testing team then, the opportunity was too good to miss.

It took a while to build the team and the department but testing was not a passion at that time.

An interesting job, yes, passion, no.

I kept working at getting better at testing, read everything I could find and tried new things all the time.

After a while, I discovered crowd-source testing (yes, uTest.com) and from that moment, the passion switch was turned on.

So, I found the passion by following the effort as Mark Cuban explains in his article :) 


.

JIM CARREY
FOLLOW YOUR PASSION, DO WHAT YOU LOVE.

http://www.businessinsider.com/jim-carreys-advice-to-graduates-2014-5




MARK CUBAN
DON'T FOLLOW YOUR PASSION, FOLLOW YOUR EFFORT.

http://blogmaverick.com/2012/03/18/dont-follow-your-passion-follow-your-effort/


  1. If you really want to know where your destiny lies, look at where you apply your time.
  2. Time is the most valuable asset you don’t own. 
  3. You may or may not realize it yet, but how you use or don’t use your time is going to be the best indication of where your future is going to take you .
  • When you work hard at something, you become good at it.
  • When you become good at doing something, you will enjoy it more.
  • When you enjoy doing something, there is a very good chance you will become passionate or more passionate about it
  • When you are good at something, passionate and work even harder to excel and be the best at it, good things happen.


DON'T FOLLOW YOUR PASSION, FOLLOW YOUR EFFORT. 

It will lead you to your passions and to success, however you define it.




MARC ANDREESSEN
DO WHAT CONTRIBUTES

http://www.businessinsider.com/andreessen-whatever-you-do-dont-follow-your-passion-2014-5

Too often, people follow their passions into fields that are simply too competitive for where their skills are in those things.

Instead, Andreessen believes one should "DO WHAT CONTRIBUTES" — FOLLOW THE THING THAT PROVIDES THE MOST VALUE TO OTHERS.


  1. Thesis: "Do what you love" / "Follow your passion" is dangerous and destructive career advice
  2. We tend to hear it from (a) Highly successful people who (b) Have become successful doing what they love.
  3. The problem is that we do NOT hear from people who have failed to become successful by doing what they love.
  4. Particularly pernicious problem in tournament-style fields with a few big winners & lots of losers: media, athletics, startups.
  5. Better career advice may be "Do what contributes" -- focus on the beneficial value created for other people vs just one's own ego.
  6. People who contribute the most are often the most satisfied with what they do -- and in fields with high renumeration, make the most $.
  7. Perhaps difficult advice since requires focus on others vs oneself -- perhaps bad fit with endemic narcissism in modern culture?
  8. Requires delayed gratification -- may toil for many years to get the payoff of contributing value to the world, vs short-term happiness.






ALISON GREEN
DO SOMETHING THAT YOU ARE GOOD AT, THAT BRINGS YOU A REASONABLE AMOUNT OF SATISFACTION, AND EARNS YOU A LIVING.

http://money.usnews.com/money/blogs/outside-voices-careers/2013/04/17/why-you-shouldnt-follow-your-passion

The problem is that "Do what you love" is terrible advice. Here's why.

Most passions don't line up well with paying careers. 

If you're passionate about poetry or salsa dancing, you're going to find very limited job opportunities for those things ..... Those are lovely passions to have, though — and often the best choice is to find a career that supports you enough to pursue those passions outside of work.

Turning what you love into a career can ruin what you loved about it. 

You might love to bake, and your friends might regularly swoon over your cakes and tell you to open a bakeshop. But getting up at the crack of dawn every day, baking 100 cakes daily, and dealing with difficult customers and the stress and finances of running your own business might have nothing to do with what you love about baking — and might sap the joy right out of it.

Do what you love," for most people, isn't a reliable way to find the right career — and can lead to anxiety, job-hopping and dissatisfaction. 

Often what makes people happy at work isn't that they're passionate about what they're doing, but rather that they have a sense of accomplishment or impact, or they enjoy the autonomy they're given, or they feel respected or useful. 

So a better goal than "follow your passion" is probably to DO SOMETHING THAT YOU ARE GOOD AT, THAT BRINGS YOU A REASONABLE AMOUNT OF SATISFACTION, AND EARNS YOU A LIVING. 




SCOTT ADAMS
SO FORGET ABOUT PASSION. AND WHILE YOU'RE AT IT, FORGET ABOUT GOALS, TOO.

http://online.wsj.com/news/articles/SB10001424052702304626104579121813075903866

... the most dangerous case of all is when successful people directly give advice. For example, you often hear them say that you should "follow your passion." That sounds perfectly reasonable the first time you hear it. Passion will presumably give you high energy, high resistance to rejection and high determination. Passionate people are more persuasive, too. Those are all good things, right?

Here's the counterargument: When I was a commercial loan officer for a large bank, my boss taught us that you should never make a loan to someone who is following his passion. For example, you don't want to give money to a sports enthusiast who is starting a sports store to pursue his passion for all things sporty. That guy is a bad bet, passion and all. He's in business for the wrong reason.

My boss, who had been a commercial lender for over 30 years, said that the best loan customer is someone who has no passion whatsoever, just a desire to work hard at something that looks good on a spreadsheet. Maybe the loan customer wants to start a dry-cleaning store or invest in a fast-food franchise—boring stuff. 

THAT'S THE PERSON THAT YOU WANT TO BET ON. YOU WANT THE GRINDER, NOT THE GUY WHO LOVES HIS JOB.

For most people, it's easy to be passionate about things that are working out, and that distorts our impression of the importance of passion. 

I've been involved in several dozen business ventures over the course of my life, and each one made me excited at the start. You might even call it passion.

The ones that didn't work out—and that would be most of them—slowly drained my passion when they failed. The few that worked became more exciting as they succeeded. 

In hindsight, it looks as if the projects that I was most passionate about were also the ones that worked. But objectively, my passion level moved with my success. SUCCESS CAUSED PASSION MORE THAN PASSION CAUSED SUCCESS.

SO FORGET ABOUT PASSION. AND WHILE YOU'RE AT IT, FORGET ABOUT GOALS, TOO.

.... He offered me some career advice. 
He said that every time he got a new job, he immediately started looking for a better one. 
For him, job seeking was not something one did when necessary. 
It was a continuing process.

This makes perfect sense if you do the math. 
Chances are that the best job for you won't become available at precisely the time you declare yourself ready. 
Your best bet, he explained, was to always be looking for a better deal. 
The better deal has its own schedule. 
I believe the way he explained it is that your job is not your job.
YOUR JOB IS TO FIND A BETTER JOB.

This was my first exposure to the idea that one should have a system instead of a goal. 
The system was to continually look for better options.

If you drill down on any success story, you always discover that luck was a huge part of it. 
You can't control luck, but you can move from a game with bad odds to one with better odds. 
You can make it easier for luck to find you. 
The most useful thing you can do is stay in the game. 
If your current get-rich project fails, take what you learned and try something else. 
Keep repeating until something lucky happens. 
The universe has plenty of luck to go around.
You just need to keep your hand raised until it's your turn. 
It helps to see failure as a road and not a wall.

If I forgot to mention it earlier, that's exactly where you want to be: steeped to your eyebrows in failure.

It's a good place to be because FAILURE IS WHERE SUCCESS LIKES TO HIDE IN PLAIN SIGHT. 
Everything you want out of life is in that huge, bubbling vat of failure. 
THE TRICK IS TO GET THE GOOD STUFF OUT.

Code Refactoring And Page Object Model


Video


On this post, I will look at ways of improving Selenium scripts through code refactoring and starting to build a page object model.


DEFINE TEST CASE


I will use again the site of the Vancouver Public Library (http://www.vpl.ca).

The test cases to be automated are related to the login page:

       SETUP

  1.  open the www.vpl.ca site
  2.  click on the MY VPL link
  3.  wait until the next page loads
  4.  click the LOGIN TO MY VPL page
  5.  wait until the next page loads


      VERIFY
  1. login does not work when using an invalid username and invalid pin
  2. login does not work when using an invalid username and correct pin
  3. login does not work when using an correct username and invalid pin
  4. login does not work when using no username and no pin
  5. login works with correct username and correct pin





GETTING READY 


The first thing to do is to inspect all HTML elements needed in the script in FIREBUG and identify XPATH expressions for finding them:

MY VPL link
//div[@class='box1']/h4/a

LOGIN TO MY VPL button
//div[@class='content']/a

USERNAME field
//input[@class='field_username text' and @name='name']

PIN field
//input[@class='text' and @name='user_pin']

LOGIN button
//input[@class='submit_button' and@name='commit']

ERROR POPUP
//div[@class='top_message']/p



As soon as the XPATH expressions are created, I will 

- start the Selenium server
- create a new Java project in Eclipse
- add the Selenium Server and Client JARs to the project
- create a new test class
- import the Selenium package to the class
- add the setUp and tearDown methods to the test class for starting and stopping the Selenium server; these methods use the @Before and @After annotations 
- create an empty test method
- run the project
- if everything done before is correct, the project should run successfully


It is the time now for adding the code to the test method for the test case:

- the open, click, waitForPageLoad, selenium commands are used for navigating to the Login page
- the type and click selenium commands are used for entering the username and pin values on the Login page
- the click selenium commands is used for submitting the login page
- the getXpathCount selenium command is used for checking if the login failed or succeeded

Run the project again and confirm that there are no errors.

The next step is to copy some of the code for all 5 login page verifications.

The code is identical for the verifications with the exception of the values of the username and pin.

Since some of the verifications need a correct username and pin, I import a new class that provides the correct username and pin values read from an xml file.

Running the project again should not return errors.






CODE REFACTORING


The following changes will be done to the code for refactoring:





1. split the test methods in 5 smaller test methods; each verification from the test case is done in a separate test method


2. since each test method takes 14 seconds to run, use @BeforeClass and @AfterClass instead of @Before and @After so that the selenium server is started once before all test methods run and stopped once after all test methods are executed; the test execution time for the methods should go down to 6 seconds because of these changes


3. create a new method for the code that opens the Login page: openPage()


4. create a new method for the code that types the username value: 
typeUsername(String usernameValue)

add a parameter to the method for the username value


5. create a new method for the code that types the pin value: typePin(String pinValue)

add a parameter to the method for the pin value


6. create a new method for the code that submits the login page: submit()


7. create a new method for the code that checks if the login was successful or not: countErrorPopups()


8. replace the code from each test method with the new refactored methods; add the values to the parameter of each method


9. Resolve any errors and run the project







PAGE OBJECT MODEL

Since openPage(), typeUsername(), typePin(), submit() are all things that the Login page does, it makes sense to create a new class called LoginPage and move all refactored methods to it.

By moving the methods to the LoginPage class, the test methods will no longer include any code that shows how the web page works.

The LoginPage class will need a constructor that gets a Selenium parameter so that its methods can call Selenium methods.




After creating the LoginPage class, change the test methods by 

- creating a LoginPage object in every test method

- prefix all refactored methods with the name of the LoginPage object

Resolve any errors and run the code.







SUMMARY

In this moment, a few things are accomplished:

- Small and independent test methods

- The test methods do not include information about how the site works

- Easy to read and maintain test methods

- I have created a Page Object class for the LoginPage.

All details on how the LoginPage works are in the LoginPage class.

If there are changes in the future for the Login Page, only the Login Page class needs to be modified.




_____________________________________________________________________________


Do you want to learn more about test automation and Java?
I will start an SELENIUM online group training on October 15.
Please see the training details here.

Learning swimming and test automation

I have started learning swimming last fall.

My interest begun while watching people swimming on lanes in an outdoor pool.

Those people were amazing.

They were gliding through water slowly, efficiently, effortlessly and very quietly.

They made swimming look so easy and simple. And beautiful ...

So easy and simple that anyone may think that he can do it. By himself .....

So I started learning. How difficult could it be to move your arms and legs in the water?

I realized shortly that I either don't do it properly or I don't understand how they do it.

I persevered though and practiced more using a swimming training DVD as a guide.

From the DVD, I learned that swimming is actually quite complicated as it consists in individual movements that need to be done in a well coordinated way.

To swim well, I needed to understand how to rotate the body in the water, how to breath, how to syncronize the strokes with breathing, how to move my legs.

Some of these things, especially breathing,  are very difficult to get by yourself.

My swimming got a bit better but very soon I stopped again making progress.

So I hired a private instructor.

This time, I committed money and time and worked towards my goal.

After 3 months of practicing drills, repeating the same thing again and again, being frustrated of not doing it well, I finally started to make progress.

I am currently at the point where I have the skills for swimming short distances and can move to the next phase of training.

What is the connection between learning test automation and swimming?

Test automation seems easy, especially when looking at other people doing it or when reading articles written by test automation tools vendors.

How difficult can it be to record a script by using a site and then playing the script back? For sure, anyone can do it by himself ....

So you try it by yourself first.

Soon, you realize how limited is this way of "test automation" and how little you can do with it.

So you persevere and learn about the need for a programming language.

You read a programming book, learn some concepts and then come back to the test automation project.

But just a programming language and a tool for recording scripts is again not sufficient.

Reading more about test automation, you learn about other concepts like XPATH, browser DOM, code debugging, abstract layers, JUNIT, code refactoring, coding patterns, test driven development .....

But the swimming, sorry, test automation, was supposed to be easy and anyone can do it by himself!!!

At this moment, the illusion is gone and you start thinking seriously what to do.

You can persevere by yourself now that you see the territory to be explored or you can take your own swimming (test automation) instructor (course).

One thing is clear: learning the new skill will not be quick, it will take time to get all the individual drills and integrate them but the end result is very rewarding… test automation code that is simple, efficient, elegant and effortlessly created ...

You can get here with patience, perseverance and lots of practice.

Same for swimming!

JUNIT Annotations, Commands and Assertions

Annotations

The following annotations are used frequently in Selenium scripts:


@Ignore - test methods that use this annotation will be ignored at run time

@Test - identifies a test method; methods that don't have @Test won' be executed at run time 

@Before - method will be run before every JUnit @Test method

@After - method will be run after every JUnit @Test method

@BeforeClass - method will be run once before any methods in that class

@AfterClass - method will be run once after all methods in the class



Commands

Some of the commands may return one or more results depending on the number of HTML elements     matched by the XPATH locator.


selenium.open(page's relative path)

usage: opens the page that has the relative path provided as argument
example: selenium.open("/selenium/search.php");


selenium.type(XPATH locator of the HTML element, value)

usage: types the value in the HTML element found through the XPATH value
example: selenium.type("xpath=//input[@name='q']", value);


selenium.click(XPATH locator of the HTML element)

usage: clicks the HTML element found through the XPATH value
example: selenium.click("//a[@title = 'a12345']");


selenium.waitForPageToLoad("30000")

usage: wait for some time for the page to load


selenium.getTitle()

usage: gets the value of the title of the current page


selenium.getText(XPATH locator of the HTML element)

usage: gets the text of the HTML element found through the locator
example: selenium.getText("//p[@class = 'abcdef']");


selenium.submit(XPATH locator of the form)

usage: submits a HTML form found through the locator
example: selenium.submit("//form[@id='HTMLFormElements']");


selenium.check(XPATH locator of the checkbox)

usage: checks a checkbox found through the locator
example: selenium.check("//input[@name='checkboxes[]' and @value='cb2']");


selenium.uncheck(XPATH locator for the checkbox)

usage: un-checks a checkbox found through the locator
example: selenium.uncheck("//input[@name='checkboxes[]' and @value='cb3']");


selenium.getXPathCount(XPATH locator)

usage: returns the number of the HTML elements matched by the XPATH locator




ASSERTIONS

The most important assertions for Selenium are assertTrue and assertEquals.


assertTrue(text displayed if the condition is false, condition)

usage: returns true if the condition returns true
example: assertTrue("No homepage URL found ",matchingCountTotal>0)


assertEquals(text displayed if expected value <> actual value, expected value, actual value)

usage: returns true if the expected value is equal with the actual value
example: assertEquals("the title is not correct", "HTML Form Elements",selenium.getTitle());


Find HTML Elements With XPATH

NEXT - Selenium Basics 6 - Annotations, Commands And Assertions



VIDEO - Find HTML elements using XPATH 1

VIDEO - Find HTML elements using XPATH 2

This post is dedicated to XPATH which will be used for finding HTML elements in the browser DOM.

SELENIUM has one more way for finding HTML elements called CSS Selector.

The following will be investigated for XPATH:

- the structure of the browser DOM

- element tags, attributes and values

- finding elements using the absolute path

- searching for elements using attribute values

- searching for elements using XPATH functions

- XPATH locators that return more than one result



Selenium RC Setup

1. install FIREFOX

2. install the FireBug add-on for FIREFOX (from https://addons.mozilla.org/en-US/firefox/addon/firebug/)

3. install the FirePath add-on for FIREFOX (from https://addons.mozilla.org/en-US/firefox/addon/firepath/)

4. install the Selenium IDE for FIREFOX (from http://release.seleniumhq.org/selenium-ide/2.5.0/selenium-ide-2.5.0.xpi)

5. install Java (from http://java.com/en/)

6. download the Selenium Server (from http://selenium-release.storage.googleapis.com/2.41/selenium-server-standalone-2.41.0.jar)

7. download the Selenium client driver (from http://selenium-release.storage.googleapis.com/2.41/selenium-java-2.41.0.zip)

8. create a Selenium folder in your C drive (or in any other location);
   copy the Selenium Server jar file in the Selenium folder;
   extract the Selenium client driver zip file in the Selenium folder;

9. start the Selenium server from the command line:
 
   start Command Prompt
   cd c:\
   cd Selenium
   java -jar selenium-server-standalone-2.41.0
 
10. install Eclipse IDE for Java developers (from http://www.eclipse.org/downloads/); make sure that you install the one for your operating system (32 bit or 64 bit)

11. start Eclipse

12. create a new Java project in Eclipse and call it VPL


Selenium Installation Video




Create a load test plan with JMeter

Related articles:

Become a technical tester while learning JMeter
Performance testing checklist

New posts: 

Selenium Basics



JMeter concepts used in this example:

- controllers: if, simple, foreach

- regular expression extractors

- user defined variables

- dynamic http requests

- response assertions

- duration assertions

- executing javascript functions

- bean shell assertions

- reading and writing user variables in a bean shell script

- writing to the jmeter log

- using listeners (view results tree)



Load Test Plan - requirements



Main URL: http://jmeter.apache.org/

step 1. Open the http://jmeter.apache.org/changes.html

step 2. Do a few validations

         a. check that version number = Version 2.10
        b. check that page load time < 1000ms
 
step 3. At the bottom of the changes.html page, there are many bug fixes links

step 4. Get the ids of all bug fixes

step 5. Go through all bug fix ids and repeat the following actions:

         a. Print the bug order number and bug id in the JMETER log
 
b. If the bug id < 58000
 
b1. Open the bug page

b2. Run a few assertions on the bug page

b2.1 Check that ASF Bugzilla exists in the page

b2.2 Check that the bug id exists in the page




Load Test Plan set up



1. Create a Thread Group with the following settings:


action to be taken after a sampler error = continue
number of threads (users) = 10
ramp-up period = 1
loop count = 1

2. Create a Simple Controller inside of the thread group; name it "Practice Tests"

3. Create a Simple Controller inside of Practice Tests; name it "Open Bug pages based on the results of a regular expression"

4. In the last Simple Controller, create the following:

- User Defined Variables config element

* it will include the variables used in the requests and assertions


- Only Once Controller

* it will be used for opening the changes.html page only once
* name it "Open The Changes page"



- ForEach controller

* it will be used for opening the bug id pages
* name it "Open Bug Id pages"

5. Add a View Results Tree listener at the same level with the "Practice Tests" Controller; this will be used for getting results from the load test



Click the image for the original photo




Create the Tess Plan details

1. in the User Defined Variables section, add the following variables:

BugIds

used for getting all bug fix id values from the changes.html page
the variable will store a list of bug id strings
default value = 0

ResultValue

used for getting the individual bug ids from the BugIds variable
default value = 0

NumberOfBugs

used for getting the bug count in the changes.html page
default value = 0



Click the image for the original photo



2. in the "Open The Changes page" controller, create a http request with the following details:


*** this matches requirement 1
Name = Changes Page
Server Name or IP = jmeter.apache.org
Path = /changes.html


3. Add 2 assertions to the "Changes Page" http request


*** this matches requirement 2


a. response assertion

Name = check version number
Response Field To Test = text response
Patterns to test = Version 2.10



Click the image for the original photo



b. duration assertion

Name = check page load time
Duration to assert = 1000 ms


Click the image for the original photo



4. Add a Regular Expression extractor post-processor to the "Changes Page" http request


*** this matches requirement 4
Name = GetBugsIds

Response Field To Check = body
Reference Name = BugIds (defined in User Defined Variables)
Regular Expression = (id=([0-9]{5}))+ 
Template = $1$
Match = -1 (important if using with foreach controller)
Default Value = nothing

This is how the regular expression will work:

- it will find all id = xxxxx values in the page and add them to the BugIds variable
- the BugIds variable will be a collection of bug ids



Click the image for the original photo




5. Add the following to the "Open Bug Id pages" ForEach controller:

*** this matches requirement 5

- Controller Settings:

input variable prefix = BugIds (defined in User Defined Variables and instanced by the GetBugsIds regular exp extractor)
output variable name = ResultValue (defined in User Defined Variables)

This is how the controller works: 
   for each iteration, it will assign one bugid value from BugIds to the ResultValue variable.


Click the image for the original photo




- Create a bean shell sampler for displaying the bug count and id in the jmeter log:

*** this matches requirement 5a

Name = Print Bug Number and ID (inline)
String myNumberOfBugs = vars.get("NumberOfBugs");
Double myBugNumber = 0; 
myBugNumber = Double.parseDouble(myNumberOfBugs); 
myBugNumber = myBugNumber + 1;
vars.put("NumberOfBugs", myBugNumber.toString()); 
String myResultValue = vars.get("ResultValue"); 
String myBugId = "";
myBugId = myResultValue.substring(3,8);
log.info("bug number: " + myBugNumber.toString() + " - bug id = " + myBugId);

Click the image for the original photo



- Create an If Controller so only specific bug id pages are opened:

*** this matches requirement 5b


Name = Open Bug Details page if bug id < 58000
Condition = ${__javaScript('${ResultValue}'.substring(3\,8))} < 58000
  This condition evaluates if the bug id (xxxxx) is smaller than 5800;
  If the condition is true, then the next http request is executed;
  If the condition is false, then the next http request is not executed;


Click the image for the original photo
    

- In the "Open Bug Details page if bug id < 58000" If Controller, create a http request:

                                                                                                       *** this matches requirement 5b1


Name = Bug Details Page
Server name or IP = issues.apache.org/bugzilla
Path = /show_bug.cgi?${ResultValue}


Click the image for the original photo

 

- In the "Bug Details Page" http request, add a bean shell assertion:

                                                                                                       *** this matches requirement 5b2


Name = assertions
String myResultValue = vars.get("ResultValue"); 
String myBugId = "";
myBugId = myResultValue.substring(3,8); 
String body= new String(ResponseData); 
if(!body.contains("ASF Bugzilla")) 
log.warn("- could not find ASF Bugzilla in the page");
else
log.info("- found ASF Bugzilla in the page");
if(!body.contains(myBugId) ) 
log.warn("- could not find the bug id in the page");
  else    
log.info("- found the bug id in the page");


Click the image for the original photo



Run the load test