Managing Knowledge Transfer Sessions

Read the article, grab the templates

%w or %W? Secrets revealed!

Delimited Input discussed in depth.

Test Case execution priority?

Getting the priority right is critical to the focus of the testing effort.

The Daily #t~log!

Video testing log.

Ask questions

If you don't ask, you won't learn. You won't teach either.

Wednesday, 1 October 2014

Ruby Selenium-Webdriver - Quick Start

Guess how old Selenium is? If you didn't know, it's now (over) 10 years old... no really! How about Selenium 2? Well that was released in July of 2011, so it's not 'new' by any means. 

If you've not had a look at it yet, now's the time! Selenium-Webdriver will allow you to execute web tests using a range of browser easier than before. You can also use your favourite programming or scripting language and a range of other tools to enhance your testing.


As always, I'll be using Ruby on Windows for this demo and assume you have Firefox browser available - let's get going!

--------------

1. Install Ruby
To do that either read the blog post here or watch the video on YouTube:
http://cyreath.blogspot.co.uk/2014/01/download-and-install-ruby.html

Set-up and install Ruby

YouTube Channel: [WATCH, RATE, SUBSCRIBE]

2. Check your Gems
We're going to need the selenium-webdriver gem. To install that, open a CMD window (start > run > 'cmd') and type gem install selenium-webdriver. You can check installed Gems by typing gem list which shows what's available and their version.


3. Start Interactive Ruby (IRB)
For this demo we'll just run commands straight from IRB. Using a CMD window type irb to start IRB.

In IRB type require 'selenium-webdriver' to start a webdriver instance so we can pass it commands to execute.


4.  Open the browser!
Yes, we're ready to start using Webdriver. Now type the following to invoke an instance of Firefox with the reference of browser.

browser = Selenium::WebDriver.for(:firefox)

If all is OK then Firefox will open. If you get an 'access' warning, just click OK.


5.  Run some tests
Now work through the following commands to run a basic test using Google.

Type: browser.navigate.to("http://www.google.com")
Google will now load in the blank browser instance.

Type: browser.find_element(:name, "q").send_keys("Hello)
This will type 'Hello' in the query text field, but not return it.

Type: browser.find_element(:name, "btnG".click)
We'll now see search results returned.


Easy!

Watch the video!



References for DYOR:




~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Liked this post?


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Ruby Basics » Part 15 | Hashes - A Quick Intro

Welcome to the first post of the second part, in our series on Ruby Basics. To see what's coming up, check out the Trello board: https://trello.com/b/VLafOlXW/ruby-basics

-----

When we looked at Arrays, we saw that collections of data were stored under a given Array name. These were accessed by knowing the integer value of the data item’s location in the array. If you recall in the Basics 1 Wrap Up, we had the following Array:

        rolesArray = ["Developer", "Tester"]

To access these we need to use [0] and [1], as in

        print rolesArray[0]
 
Later on we assigned David or Alan as one of these roles and this worked fine. But what if we now wanted to assign them individual salaries, periods of employment, holidays allocated or other relevant data. We could create Arrays and put the data in the same sequence as the employee array. For example we might set-up:

rolesArray = ["Developer", "Tester"]
rolesHolder = ["Dave", "Alan"]
rolesSalary = [40000, 35000]
rolesHoliday = [25, 25]
 
I’m guessing you can see that’s all well and good if everything stays in order. For those with a little Database knowledge this problems with the above approach scream even louder. What we need is a way to explicitly pair the data above with a key bit of data that won’t change. In this case that key bit of data is the employee name.  How can we label the various bits of data with the employee name?

What we need is a key --> value pairing of data, so no matter what order they are stored, we can find, edit, update, and delete the correct one. As luck (Ruby) would have it, what we need is a Hash.



YouTube Channel: [WATCH, RATE, SUBSCRIBE]


A Hash is a collection of Key-Value pairs. Hashes are also referred to as associative arrays, maps and dictionaries. They’re like Arrays in that they’re still variables storing variables, however unlike Arrays the data isn’t stored in a particular order. Also unlike Arrays, we don’t push/pop data into and out of the Hash, we simply insert and delete Hash values. Let’s look at making a Hash for some of the above data.

We can make a new empty Hash in a similar way to a new empty Array;

        rolesHash = Hash.new

If we print the above, of course nothing will be returned. As we then acquire data to add to it, we can insert the data by giving the key-value pairs:

        rolesHash["David"] = "Developer"

Try running the entire snippet below:

rolesHash = Hash.new
puts rolesHash

rolesHash["David"] = "Developer"
rolesHash["Alan"] = "Tester"

puts rolesHash

Here we add two key-value pairs to our newly created Hash and print the entire Hash out, which looks something like this:

        {"David"=>"Developer", "Alan"=>"Tester"}

If we wanted to find out what role David was currently in we could look it up using the key:

                    puts rolesHash["David"]

If you try this with a name that is not in the Hash, then the result will be nil which isn’t very informative. A better way is to define a default value, for example:

                    rolesHash = Hash.new("No Role Assigned")

Try it again and watch the default message get printed.

Adding to the Hash is good, but we also need to delete items too. To do this we simply call the delete method on the hash and specify which key we want deleting.

        rolesHash.delete("David")

If you’d prefer to just build out your Hash from the start, you can do that too.

salaryHash = Hash["David" => 30000, "Alan" => 35000]
puts salaryHash


We’ll leave the basics of Hashes there, as always have a look at the Ruby docs to see more of the methods available. Later on, we’ll look at some of the more complex aspects of Hashes, but for now we have what we need!

Monday, 29 September 2014

NightwatchJS - JavaScript web automation with Selenium-Webdriver

As the website says "Nightwatch.js is an easy to use Node.js based End-to-End (E2E) testing solution for browser based apps and websites... Simple but powerful syntax which enables you to write tests very quickly, using only Javascript and CSS selectors."

If you're happy writing a bit of JavaScript, then Nightwatch is an interesting option to look at. It uses Selenium Webdriver at it's core and so fits the tech stack commonly used for web testing.

This post is a no-fluff Quickstart to get nightwatch.js set-up on a WINDOWS system - becuase as usual the Nix* crew have posted for that side already. Here nothing is 'explained'. For a more details and how to set-up on other systems, see the Nightwatch website and Github repo.

https://github.com/beatfactor/nightwatch
http://nightwatchjs.org/ 

This is describing set-up on a **Windows 7 Professional** 64-bit system with Firefox installed. 

For the epicness, in a new tab, open this http://www.infinitelooper.com/?v=nu6ht1CwZO0 and leave it open until you are complete!

Mark

***

1) Base folder  
  • On your system create a folder called dev on the root, e.g. C:\dev

2) Install Node.js
  • Under C:\dev create a new folder called nodejs.  
  • Go to http://nodejs.org/ and install nodejs in the new folder, ensure you include the npm (Node Package Manager) tool in your installation.  

3) Install nightwatch.js  

  • Under C:\dev create a new folder called nightwatch.  
  • Got to Start > Run > and type 'cmd' to get a console window.  
  • Type `npm install nightwatch` and note the location and structure of the install.  

4) Get Selenium Server  
  • Download "selenium-server-standalone-{latest version}.jar" from; http://selenium-release.storage.googleapis.com/index.html  
  • Place the file in the nightwatch/lib folder created as part of the nightwatch.js installation.  
  • Rename the file to `sel-serv.jar` for ease of reference.  

5) File to call the runner  

  • On your system navigate to C:\Dev\nightwatch\node_modules\nightwatch  
  • Create a new file called nightwatch.js
  • Add the following line and save the file; `require('nightwatch/bin/runner.js');`

Basic set-up is now complete!  


6) Start Selenium
  • Open a console window (or reuse the one from step 3) and navigate to: C:\Dev\nightwatch\node_modules\nightwatch\lib
  • Now type `java -jar sel-serv.jar` to start Selenium Server.  
  • Open Firefox and navigate to `http://localhost:4444/` to check the server is up (ignore the 403 error).  

7) Run some tests!
  • Open a new console window.  
  • Navigate to C:\Dev\nightwatch\node_modules\nightwatch\
  • Run all example tests by typing `node nightwatch.js`  
  • Run a group group of tests by typing `node nightwatch.js -g google`  
  • Run a single test by typing `node nightwatch.js -t examples/tests/nightwatch.js`  


Yay!  Your first nightwatch.js tests!

Mark.

p.s. Look out for the post on creating a VBScript report viewer for Nightwatch.



NightwatchJS


Monday, 22 September 2014

Testing Search

I got thinking about Search testing the other day and ended up waking at 4am to scribble a mind-map of thoughts before I lost them. As you do.

The main thought was how Search testing traverses the three main layers of testing we typically consider.

* Where - the web front end in which the user builds their search queries
* How - the Search 'engine' that does the work of polling the available data

* What - the data that is being searched


Target of the search
Before any testing commences, we need to understand as fully as possible what it is that can be searched for. To do that we need to be clear on the data that is the target for the search. Though reasonable to expect the searched for data to be static in a database, the returned results might also be dynamically generated by the search query. Not all data returned may be under the control of the business, remember the search may also be fed by external data.

- What data is the user searching for? (e.g. products, account records, flights, ...)
- What data sets are available? (e.g. product attributes, transactions/payment types, current/future flights, ...)
- What is the source of the data? (e.g. static data, dynamically created data, external sources, ...)


The Search Engine
The most informative way of learning this is via the API documentation for the search engine. With this we'll know what can be passed to the engine and so shape the scope and structure of allowable queries. Some good public examples of Search APIs are those for Google (https://developers.google.com/custom-search/docs/overview) and Twitter (https://dev.twitter.com/rest/public/search):

If your development team can't provide the API docs, ask for access to the Java docs, Unit Tests or whatever else can inform you about the implementation specifics. In my experience, the design of search is rarely sufficiently detailed enough for testers, in specification documents or requirements statements. Indeed in a more agilistic setting it's very likely this detail is closer to the code - get sauce! You can't properly test the implementation from just the original specification.

To counter the obvious challenge here of 'you don't need to worry about that... just run your tests... confirm the requirements have been met... ', as part of the implementation team you are not restricted to just looking at the acceptance tests or requirements. As part of the implementation team, in the tester role, you are working with equality with all other roles and so the code, unit tests, etc. are not 'off limits', just as your tests and automation code is not off-limits to anyone. If you are told they are, then you are not in an agile team or whoever is saying this needs to get off the agile team. (Whether you can understand the code, tests, etc. or not is another matter)


Building Queries
Our next concern close to the user, is the UI and how it allows the search queries to be crafted.

- How can a search query be entered? (free text, drop-down, ...)
- How can search options be used? (Boolean, switches, ...)

Now that we have knowledge of what the search functionality actually is, as a component of the system, let's think about what testing will be needed.

Functional
We clearly have out typical functional testing, that will include submitting search queries. However, we need to break that down too, to ensure we're clear about what we're actually testing.

As we have a UI, we'll need to test the functionality a user is provided to build a search query. This might be a simple free-text field like Google, where the user just enters whatever text they want with no switched, drop-downs or options. Be aware this can have hidden nuances too though. At first glance Google search functionality is just a text field, but in fact we have a bunch of ways to structure our search query.

For example, you can enter 'define: testing' to get a dictionary definition or search for files in a given directory, try '-inurl:htm -inurl:html intitle:"index of" + ("/secret")' to see how not to hide your password files and pictures of your ex girlfriend. Don't do that search in work by the way! If you've reviewed the API docs or something similar you should know if the above types of searches are available to you.

For searches constructed by selecting from drop-down boxes, using radio buttons, etc. it'll be more apparent what choices you have. Again, be careful to understand where the data in drop-downs for example is coming from. As always, view source. Is that drop-down populated via an Ajax call, a fixed list in the HTML or a list from another JavaScript? Depending on how those selectable search options can be chosen, it will affect the specific test cases that will be possible. Remember to do some equivalence partitioning where any lists are concerned, like other tests it's highly unlikely you'll need to test all combinations.

Obvious initial tests will be data entry, using valid and invalid inputs, leading spaces, special characters and all the other standard cheat-sheet heuristics. However, we need to be careful here as this is more likely form-field input validation, which is not search testing. Be sure again to view source and see where that validation is taking place, client or server side. Hopefully it's not an embedded JavaScript, check source and if you see a src=validation sounding JavaScript name, save a local copy and inspect it. Oh wait, you don't need to do that because other members of your implementation team have shared these items via your CVS / Git / etc. and you can review them.

Accuracy
We've all experienced using a search engine and getting a result that is nothing like what we were after. The underlying challenge here is a code and engineering problem, but it's part of our job to show how inaccurate results are. The definition of this will likely be a combination of referring to requirements and our experience / gut-feel. When we use search engines ourselves, we'll often get results that are technically correct and yet wrong. It'll be a bunch of blog posts on a given topic where half are barely relevant or a search for 'coco' that uncovers a family (un)friendly set of pictures of a lady looking rather 'distorted'. 

Consistency
When we perform a search it's reasonable to expect the results will be the same if the underlying data and search engine logic are the same. This will form the basis for some of the regression testing we'll want to conduct over successive releases.
However, there are occasions when the same search string will bring back different results.

* The search database is replicated and data varies between the databases
* Data has changed since we last run the query

This should be noticed due to a problem with search result consistency. Either the search string will be consistently different than was returned in a previous test run or it will sometimes be different. Where data is different consistently, we just need to validate this is as expected then update our script. For results that should be the same but are sometimes as expected and at other times not, we need to look at where the query is going. A common problem for search consistency is the combination of data replication across multiple data-bases and routing due to load balancing. When we conduct our search, we might not be 100% certain as to what data sets we are hitting and which server our query is hitting. These are questions to take up with whoever is fulfilling the Dev Ops / Infrastructure role in the team. We need to understand the data replication process, are all servers copied to at the same time or in some kind of order? Is there a back-up process that takes servers off-line when we might be testing?

For all of the above we could be using a simple tool such as Selenium with a dashboard to show results. Selenium allows us to run the tests in a loop, vary the query, save down results files, etc. What i would not use it for, although I know it does get used for this, is performance.

Performance
Another aspect of search is the speed at which we get back our search results. We'd expect this to vary but not by much, usual changes in network traffic and resources on machines are fine to a degree. When we start to see notable slowdowns then we need to investigate. To help with testing of performance use a performance testing tool, as above, Selenium ain't it. Grab a copy of JMeter if you're working with open source tools. It should be an easy matter to replicate your test in JMeter and build them out into a test plan that let's your performance test search results.

In closing
In this post we've looked at the fact search testing is not just putting a few search strings into a text field and reviewing the results don't look wrong. We have the full scope of functional and performance, along with data accuracy and consistency to consider. To test thoroughly we need sight of the requirements but also the code or API docs and an understanding of the network infrastructure that's in place.


Mark




Testing search functionality on websites and applications


Thursday, 14 August 2014

Why you're NOT a Software Testing Expert, probably

I see it often on people's profiles and CVs, Expert. It's one of those words that get my attention straight away - and is often badly defined. I'm sure that trying to work out where you are, on a scale from clueless to expert, is something I'm not alone in doing. I was recently invited to review a training course on the basis feedback from an expert like me would be useful. Hmm...

In a recent set of interviews for my next contract and (shock) a permanent role, I've been thinking about this more than often, as you would. It's important to be clear about what you do and don't know, then answer truthfully... no really ;). In some of the calls I've been asked to rate myself on a scale of 1 to 10 either for specific skills and technologies or say as a tester or manager. This creates a problem, given my expectations of what an Expert is, being set so high. The problem being, I rank myself much lower than perhaps I would be expected to say. I could state big numbers, but I don't have an ego the size of a planet. I probably don't have 'marketing' smarts either.

Thinking through what an expert or a 10 is, I came to the conclusion that people at this level are almost unheard of, certainly rarely encountered and almost definitely not doing telephone interviews. That's why you're probably not an expert, probably. We could argue on the 'label' but let's use Expert as the top and Clueless as the bottom. I'll make up ones in between. The reason you're probably not an expert is due to the second issue, the labels are used too broadly.

Imagine I introduced myself as an Engineering Expert, Medical Expert, Physics Expert, Agricultural Expert, Legal Expert. You would immediately need to ask "In what field?" or maybe "In what area?". These descriptions are too broad. There's no way you're a 10 in brain surgery and a 10 in gerontology, you won't be a 10 in family law and a 10 in contract law, you can't be a 10 in civil engineering and a 10 in aeronautical engineering. You can't therefore be a 10, a Software Testing Expert. By definition it doesn't make sense.

Just at a high level we could break testing down into say Functional, Performance and Security, though we could add in other major testing areas. Straight away with just these, I'm sure you'll agree we all know people who are more 'expert' in some of these areas than others. Add in that there are people who focus on test management or on the other end of the scale perhaps automation. Even then, when we say "they're an automation expert", we mean they have expertise in a certain set of tools, technologies and techniques (TTT).


OK then, so when asked to rate ourselves and if we're an expert how might we define that?


On a scale of 1 to 10...

1 - Clueless
You have no awareness of the TTT. When someone says Git, Capybara, C and Java to you, you think it's about animals who are idiots living across the sea on an exotic island.
But hey, well done for reading this blog, stay a while, click an ad. Now go and get yourself the ISTQB Foundation certificate and become a real expert! (that was a joke...).


You resolve to continue pushing yourself. Perhaps there's more to you than you thought.

------------------
Given the above, the rest of us fit somewhere after. However, one more refinement, we don't need to worry about exact numbers. In any given role your skills and aspects of them, will be needed to a greater or lesser degree. "about a nor n, depending on the demands of the project" is a reasonable answer when asked about your skill, on a scale of 1 to 10.

------------------



2 to 3 - Beginner
At this level you've been exposed to the technology, though your understanding of it is limited. You are starting to remember what you are shown step-by-step to do, though constant guidance is needed when encountering issues outside of direct tuition. As a beginner you won't yet understand how the TTTs fits into the overall testing domain. You may recognise the need, e.g. why continuous integration is a good idea, why end of day reporting is valuable, but you carry out tasks as shown, in a rote fashion. With more practice, you start to take on more complete tasks under guidance and begin to need less day to day reference to mentors or help sources.


You realize that all your life you have been coasting along as if you were in a dream. Suddenly, facing the trials of the recent past, you have come alive.
 

4 to 5 - Able
Now you've started to gain some ability to use the TTT day to day as expected. You're fully comfortable with the basics and have started to understand why the TTT is needed. In addition, you now start to see what value it adds, how it integrates with and supports other TTT. You can be readily delegated to but might not always be completely successful or fully efficient in using the TTT to complete a task. Some remediation by more experienced staff might be needed, though when given you gain useful insight into whatever was previously unclear and make positive advances in your overall ability.


You sense yourself more aware, more open to new ideas. You've learned a lot about Software Testing. It's hard to believe how ignorant you were -- but now you have so much more to learn.


6 to 7 - Capable
At this level you're able to carry out whatever needs to be done, with guidance and support not expected to be needed. You fully understand how the TTT works and integrates with others, have insight into common and more obscure issues and problems that occur. You can now start to mentor others in the team and comfortably bring the TTT to projects as part of your professional tool-kit. When thinking of what you 'do' and how you work, the TTT will be part of how you define yourself and your capabilities. many sources of information on the TTT and others people's understanding of them are notably less than yours. You may start to find it difficult to discover new ways of improving your understanding and use of the TTT because what's to learn is getting less and less mainstream, more difficult to find.


It's all suddenly obvious to you. You just have to concentrate. All the energy and time you've wasted -- it's a sin. But without the experience you've gained, taking risks, taking responsibility for failure, how could you have understood?


8 to 9 - Competent
Once you become competent you've gained a full professional understanding of whatever TTT you're working with. By definition you are now possessing all the necessary ability, knowledge, experience and skill to do something successfully, efficiently and with complete consistency. Doing it with your eyes closed... on auto pilot... hardly thinking about it - are all phrases that people are whispering behind your back. You will certainly understand the shortcomings and limitations too, identifying ways to work around them or improve them and integrate with other TTT. By now you'll be known as a key go-to person for the TTT in the profession and likely blog or write on the topic. You competency is so complete, that you can begin to subvert the methods and reasons for using the TTT to deliver unexpected improvements and start to re-wire the ways of working and benefits derived.


You're really good. Maybe the best. And that's why it's so hard to get better. But you just keep trying, because that's the way you are.


10 - Expert
There has to be a level that is the absolute pinnacle of knowledge and expertise, a level so high it cannot be surpassed. This is the level 10 Expert.


To be a level 10 Expert you invented the TTT, several years ago and others are still playing catch-up. You published a book on it and/or get speaking engagements to explain the awesomeness to the masses. Alternatively, you have gained such a level of understanding that you have gone back to the inventors and pointed out where they're getting it wrong, heck you probably decided they're so missing the point that you went and spun off your own TTT to show how it REALLY should be done. You don't look for jobs with this TTT, they come to you.


You'll never be better than you are today. If you are lucky, by superhuman effort, you can avoid slipping backwards for a while. But sooner or later, you're going to lose a step, or drop a beat, or miss a detail -- and you'll be gone forever.

(it was going to be this, but the above was wittier ;} )

Like a Spartan of the tech world, you search the globe for your equal, but it's a lonely pilgrimage - Mark Crowther


Extra bonus points if you can place the quotations...

Mark



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Liked this post?


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~




http://en.reddit.com/r/Morrowind/comments/1s1emv/i_find_the_levelup_messages_very_inspirational/
http://www.elderscrolls.com/morrowind/

Wednesday, 6 August 2014

Women - Pay and Workplace inequality

Despite great progress, women still experience a lot of pay and workplace inequality. In the last 10 to 15 years there's been a big push from government, companies and other organisations to reduce the level of inequality. Some approaches have worked well, others not so much. That's always the case of course, but at least the general effort has been towards a noble objective. Just in case your reaction is to think this isn't a big issue, let me assure you it is. It is both in and of itself, but also in context of the women's general situation.

There are many aspects of women's situation in the world that we should be shouting about and demanding change on. From the disproportionate level of oppression and violence women suffer the world over, to the many derogatory elements our language is littered with, there is an absolute shopping list of negative stuff that's directed at women, which should be so much in the depths of history they seem as ridiculous as women not having the vote or not being allowed to drive. Oh wait, depending on your country women still don't even have those rights!

Just to be clear and before anyone switches off in a possibly oh-so-predictable-way, I'm no 'feminist' or whatever the male version is. It's too much us-and-them and has had its time. We need a more inclusive 'something-ist' to describe the current state of affairs. Something that applies equally to men and women of all races, cultures, classes, education levels, etc. I have a rather utopian trans-humanism/ist perspective on how the future society could be if only we could 'dump the baggage', as a friend once summarised the needed action as. However, before we can arrive at the next step of this inclusive perspective, we need to address the glaring inequalities that women (and other 'groups') have to endure right now. A glaring in-your-face issue we are presented with everyday as technologists in our places of work, an issue we can call out easily, is pay and workplace inequality for our female colleagues. but what is it, why should we care and what can we do about it?

Let's talk pay, I suspect most people will agree women can easily find themselves earning less than men. It seems that typically a woman can expect to earn around 10% less than a man during her working life, when she gets to 50 that opens up to around 20% less. What might a lifetime's earning loss look like then? Let's keep the figures modest and easy to work with as this is an illustration not a scientific reckoning. Say she starts at 25 after Uni and job hunting, on £35k and gets to £50k by 50. that's an average of £42.5k per year x 25 years or £1,062,500 - hey not bad and she still has say 20 years to work. Oh except there's a few catches to this. Firstly she could have been earning an extra 10% if she was a man, another £106,250 which would be nice in the pension pot at least. Add to that 43% of women quit work when they have a family, if so that salary is cut by around 10 years, assuming they go back to work after that period. (*assuming you're leaving on your own and not one of the 30k women who get sacked for being pregnant each year).

That means our typical mum could be sacrificing and losing out on over £400k before she reaches 50. Turn it around, on reaching 50 the man has another £400k in his pocket (well... subject to tax etc). If the size of that amount isn't a shock to you (well done you for earning crap loads!), how about on your 50th birthday I give you a gift of £400k? Would that take your breath away? Wait a minute, added together then as a man, the above rough figures will see me earning £1.16m and my wife is going to expect to earn around £740k, assuming she can get back into work at the same pay grade after 10 years? Hmm... why do I doubt that. (Assuming women even earned this, 70% of people on the national minimum wage are, you guessed it... women)

But wait, at least 57% of women stay in work and keep earning... 10% less but hey, small fry compared to the above . Just to give a nice kicker to the story though, two more things. Women don't all quit work at 50. In fact there's been a rise in the numbers of 50+ working women. They get an extra insult by earning even less than men at this point. Typically up to 20% less. That's assuming they're fit to work, as disability and long term illness, that prevents her working, hits women worse than men when reaching 50. According to the TUC, 3 in 5 women over 50 are in work, with most earning less than £10k per year through part time jobs. In other words, 40% of women 50+ are not in work, those that are, many earn under £1k per month. It's estimated there are around 2.8 million part time working women 'employed below their potential'. Great, just as the run-up to retirement really begins. To which... the extra kicker.

Employer pensions typically pay an amount of your salary towards your pension. It may be that you pay a % and they match it or top it up to a %. For women we already just discussed they get about 10% less salary, so the overall contribution to pensions during their working lives, mums or not, is down 10%. Go Google 'pension poverty women' for more on the disaster zone that women's pensions are. Well don't worry, you only need 25 to 30 years of National Insurance contributions from your work life to qualify for the full state pension, oh except you had kids and now 40% of women aren't in work over 50... tricky. Does anyone else feel like swearing yet?

Even with my crappy maths, that fact that women are getting a raw deal just on pay are not in question. I don't have the answer to the above, it's complex and there's not single 'thing' to change. But, at the very least, when women are in work they should be getting equal pay. The 'you chose to have a family' argument I can roll with, but at least enable women to get employed and earn with equality when they are working, at whatever age. I can't believe that in 2014 we're even talking about this!

As fellow technologists we need to make it clear that in our workplaces we absolutely will not accept anything less that complete equality. In fact out of fairness I'd go for inequality in favour of women. Make it clear to your employers it is a matter of concern for you and you want to know what they're doing about it. If you run your own business take steps to address this.


As part of the community, support women in tech by demanding equality in pay, career development and access to roles. Whatever you can, one battle at a time is better than doing nothing!

I'll leave it here, we've not even covered workplace inequality. Blimey, big topics.



Mark

https://www.nomisweb.co.uk/census/2011/DC3302EW/view/2092957703?rows=c_sex&cols=c_age

http://www.thisismoney.co.uk/money/pensions/article-2521260/Almost-twice-men-107-basic-state-pension-women.html

http://www.nidirect.gov.uk/how-your-state-pension-is-worked-out

http://ukfeminista.org.uk/take-action/facts-and-statistics-on-gender-inequality/

http://www.tuc.org.uk/equality-issues/gender-equality/gender-pay-gap-twice-large-women-their-50s






Tuesday, 5 August 2014

Ruby Basics - Wrap Up 1

Hey All!

Well here we are, 15 videos in and already at a wrap up of what we've learned so far!

In this post, let's do a code walk-through of a script that includes the elements we've covered in the rough order of the videos. Be sure to check out the Ruby Playlist on YouTube if you've not done so already. Grab a copy of the script here



YouTube Channel: [WATCH, RATE, SUBSCRIBE]


The first thing to look at is getting user input and assigning the data to local variables. Here we do a basic puts and using a local variable called userFirstName we assign it a value the user enters. On this value we call the string class methods of chompdowncase and capitalize. In the second set of lines, we use #{interpolation} and call a string method on that too. Quite a lot in 4 lines!

# Let's declare our LOCAL variables and get some values straight away (Video 2 and 5)
puts "Welcome, what's your first name? (Dave, Alan or yours)"
userFirstName = gets.chomp.downcase

puts "Hi, #{userFirstName.capitalize}. What's your surname?" 
userLastName = gets.chomp.capitalize

Next we assign a global variable so we have access to it anywhere in our script, pretty similar to what we've just done. Global variables are identified by the $ symbol.

# Let's create an example GLOBAL variable (Video 6)
$globalNameText = "User name is: "

While we're looking at variables, let's declare an instance variable and so some concatenation. You'll recall that instance variables are identified by using the @ symbol. (We'll look at Class @@ later). We also snuck in another string method, upcase.

Here there are two ways to concatenate text, using either the + symbol or << symbol. Ruby docs tell us that + creates a new string, where as << appends the string to whatever precedes it. In terms of speed and memory usage this could be significant on large data sets! Let's be clear, userFirstName + " " creates a new string that now includes a space. Doing << UserLastName just adds it to the existing string.

Can you design a test to prove this?

# Now we'll make an INSTANCE variable from the user name (Video 7)
@userFullname = userFirstName.upcase + " " << userLastName
#upcase is also string method 

Next we define a Constant, which we do by using all uppercase. Age isn't a good exmaple but it works for our purposes :) As we're getting a number, we don't use the usual downcase, as that wouldn't make sense. Try it and see what happens.

# Finally let's get a CONSTANT in use (Video 8)
puts "#{userFirstName.capitalize}, how old are you?"
USER_AGE = gets.chomp #we UPPERCASE Constants to differentiate against variables

We print out a message using our Global and Instance variables, showing concatenation works just fine on these too.

# Put the correctly formatted name to screen
puts $globalNameText + @userFullname

As we want to have data already stored for our program to use, we next create a simple array of data, just with strings in this example.

# set up an array with the template roles (Video 9)
rolesArray = ["Developer", "Tester"]

Now that we have our data, let's do some evaluation of it and decide what the outcome of that should be. The first step is a Case statement, against whatever names the user entered above.

Here, we respond to the user with data we've pulled out of the array we just set up. You'll recall that we index into arrays starting at position 0. So when we run the script, Dave will be assigned the role at position 0, a Developer.

# Depending on what the users first name is we'll respond with more details (Video 10)
case userFirstName
when "dave"
    puts "#{userFirstName.capitalize} you are a #{USER_AGE} year old #{rolesArray[0]}"
    userRole = rolesArray[0]
  
  when "alan"
    puts "#{userFirstName.capitalize} you are a #{USER_AGE} year old #{rolesArray[1]}"
    userRole = rolesArray[1]
    
  else
    puts "You must be a new member of staff, welcome!"
    
end

Next, we'll ask about a career change and instead of using a Case statement to control the flow of our response, we'll use a basic if and then a nested if statement.

As we've discussed before, we can evaluate the response using regular expressions or direct evaluation.

# Here we use a nested IF to check for career changes (Video 12)
puts "Do you want a change of career? (Yes or Y or No or N)"
careerChange = gets.chomp.downcase

if careerChange =~ /\A(yes|y)\z/ then
  
    if userFirstName == "dave" # (Video 11)
      puts "#{userFirstName.capitalize}, you are a now a #{rolesArray[1]}"
      userRole = rolesArray[1]
      
      elsif userFirstName == "alan" or userFirstName == "Alan"
        puts "#{userFirstName.capitalize}, you are now a #{rolesArray[0]}"
        userRole = rolesArray[0]
        
      else
        puts "Easy #{userFirstName.capitalize}, you just joined us!"
      
    end
  
  elsif careerChange =~ /\A(no|n)\z/ then
    puts "Great, keep up the good work!"
    
To finish off the main body of the example script we'll now use a While statement, to keep asking a question until a condition is met. We've also snuck in an If ternary to decide how to respond if the hoursWorked value is under 8.

# Now we'll check if the user has done a days work! 
hoursWorked = 0
userRecord = [userFirstName, userLastName, userRole, USER_AGE]

while hoursWorked < 8 # we could do an UNTIL hoursWorked == 8 here instead   # (Video 13)
  puts "How many more hours have you now worked #{userFirstName}? (enter 0 to 8)"
  puts "total hrs worked is so far: #{hoursWorked}"
  
  hoursWorked = hoursWorked + gets.chomp.to_i

    hoursWorked < 8 ? (puts "Keep going, the day's not over!") : (puts "Well done, go home and relax.") #example of if Ternary (Video 13)
      
end

Just to finish, let's add a new data element to the end of the UserRecord array and print the results.

userRecord.push hoursWorked #Pushing to an array (Video 14)
puts userRecord

Don't forget to grab a copy of the script and play through it yourself!

Mark.


Read More