Wednesday, 8 March 2017

Here we
are, Day 6 and pretty much a continuation of yesterday. I suppose I should say
refinement or refactoring. Compared to the approach taken in yesterday’s
session I scaled this right back to something simpler. Why? Here comes today’s
(and yesterday’s) real learning.

I was
breaking the golden rule of taking it one step at a time. Instead I was trying
to work out what the overall solution looked like then code it up. That was doomed
to failure so I went back to baby steps and simplified things.

First off, recall the (cut down) testing problem from yesterday:

You have a website with 2 navigation links. The expectation is more
links will be added in the future. The test must check the known set of text
links are present and if any new ones have been added.

That’s the
first part so let’s work out some code for that.

Here’s the
list of expected links:

publicenumlinks

{

News,

Sport

}

We need to
a) locate the links section and b) count how many links there are on the page:

Tuesday, 7 March 2017

Today’s session was a bit all over the place. I spent most of the time imagining what I think the solution to my current problem could be, than actually solving the problem in code. Such is the way sometimes I guess but I certainly look forward to having mental models of code patterns in my mind to apply more readily.

Here’s the problem:

You have a website with 4 navigation links, 3 are text and 1 is a link under a company logo. The expectation is more links will be added in the future, they might be text or images. The test must check the known set of text links or linked images are present and if any new ones have been added. If new ones have been added, this should simply be reported and the known set tested anyway. The classes/methods for this must be reusable, to cover other sets of links across the website.

To do this I started splitting out the list of known links into a Dictionary

publicstaticIDictionary<string, string> knownTextLinkAndURLList

= newDictionary<string, string>

{

{ "News","http://www.bbc.co.uk/news/" }

{ "Sport","http://www.bbc.co.uk/sport" }

};

Then I created a method to loop over the links by looking for the link text

var pageNavigationElementException = $"I expected {navigationLink} but it was not located";

thrownewException(pageNavigationElementException);

}

}

}

Which used a reusable extension in the If statement I copied down from Stack Overflow:

publicstaticbool IsElementPresent(By by)

{

try

{

Driver.Instance.FindElement(by);

returntrue;

}

catch (NoSuchElementException)

{

returnfalse;

}

}

This seems fine for checking over text links, but we need to do that then check the actual link is correct. This is assuming we're concerned link text may be written incorrectly / against an agree style and that the link applied might vary, say news.bbc instead of bbc.co.uk/news for example.

Two things to investigate further then; 1) How to check both link text and link, 2) How to confirm there are no new links added (we can already check if any are removed or their links changed)

Monday, 6 March 2017

Day 4 of the 100 Day Deep Work challenge actually happened on Friday, but as I don’t do IT
stuff at the weekends here’s the posting today!

One thing I’ve been doing for simplicity sake is putting the
various usernames and passwords used in tests into its own Class file. As I’m
always working on test systems it didn’t seem to be an issue. However, the
general convention is that these Usernames and Passwords should be protected to
align with the security policy of the company you’re testing for.

That makes sense, after all you might have an Admin user who’s
details make it into a live deployment. With tester tests integrated into the
same place as unit tests and code, the risk is there.

So, how to move those
details out of the Class file and include them in the Configuration file?

Configuration
Settings

In Visual Studio’s ‘Solution Explorer’ you’ll see your
project has an app.config file, double click and open it. Inside the configuration
elements we can add appSettings and include details of our username and
password as a key/value pair.

<?xmlversion="1.0"encoding="utf-8" ?>

<configuration>

<appSettings>

<addkey="AdminUsername"value="testuser" />

<addkey="AdminPassword"value="Password1"/>

</appSettings>

</configuration>

Naturally a lot more can be added here, such as system
configuration details, but for now let’s stick with these two items.

Calling the
appSettings items

To call the items from the app.Config file we need to add a
call to our test like this:

LoginCommand

.LoginAs(ConfigurationManager.AppSettings["AdminUsername"])

.WithPassword(ConfigurationManager.AppSettings["AdminPassword"]);

In practice however, I’m
seeing the norm appears to be to call the AppSettings items via a separate file.
I’m not 100% sure why at this point, but I’m assuming this is further
abstraction. Moving anything that might change even further up to the page
object level and out of the test. For example we might create a separate class
to hold the user list for this test

Saturday, 4 March 2017

This week I was trying to find/learn a way to create pattern
of code in some of the automation I’m working with. The pattern would allow the
listing out of collections of items, say links or page tabs, then iterate over
each one testing they are working as expected.

Page Object / Page
Flow

There are some simple ways of doing this, but the challenge
was to follow coding standards used in the project. One aspect of which is to
follow the Page Object / Page Flow model. Essentially that means having
automation tests that are separated from the code that describes the page
elements and how we interact with them. So how to create a test that can call
page-stuff in a generic way.

Enumeration

Enums in C# allow us to make unordered lists of items (I
learned there is an ordered list too), like links or tabs, then use them in
other things like Dictionary lists. Where we could then have values
(definitions) assigned to the list items. That seemed like a good way to
declare an item of interest to check in the test and give it the ID as a string
from the HTML on the page.

Here’s what the main pieces of the header section I wanted
to find looked like in an enumerated list.

publicenumenumElements

{

Logo,

ApplicationName,

Welcome,

OrgSelector

}

Dictionary

To assign each of these items of interest a string value
that matches the ID in the HTML I used a Dictionary list, knowing I could pull
out the value element (the string) later for use in the actual test. Here’s how
the Dictionary pulled in the item and assigned the value.

publicstaticIDictionary<enumElements, string> ItemName

= newDictionary<enumElements, string>

{

{ enumElements.Logo, "logo" },

{ enumElements.ApplicationName, "application-name" },

{ enumElements.Welcome, "welcome" },

{ enumElements.OrgSelector, "org-selector" }

};

The Unit Test

The objective here was to see if I could build a Unit Test
that did NOT contain the actual values being tested. The idea there of course being
that if the page changed, the test would still stand; just the underlying
values would need changing. (Idea: can we make the dictionary items more
generic?)

Here’s the Test Method from the unit test:

[TestMethod]

publicvoid TestMethod1()

{

foreach (var item in ItemName.Values)

{

Console.WriteLine($"We have: {item}");

}

}

The theory here being – if we can do a WriteLine on each
item Value, then we could replace Console.Writeline with meaningful Selenium
test code. That could be asserting the presence of each item in the page for
example or clicking on it. Running the test worked and the output was a list of
the string Values.

Phew! That only took 2 days, but now we have a pattern for
building a list of pretty much anything and testing them in an iterative
fashion. Literally, if we have a set of links, tabs, items in a drop-down; the
above will make it easy to test them.

Thursday, 2 March 2017

Thoughts, discoveries and blockers from Day 2, posted a bit
late as I was having some computer issues last night, got to love system updates!

The plan yesterday was to study iterating over multiple
elements of a page using Selenium, such as sets of links or dropdown items. It’s
one of those problems where I’ve solved it before but I always felt it was in a
crude way. However, I got entirely side tracked by the idea of identifying the
Div section in which a set of links, for example, might appear instead of the individual
links. That feel more like a general UI based test, whereas checking for individual
links is more a unit test.

It all depends on the purpose of the test of course, but at the
UI level we really should be looking at user journeys and workflow, how the
user traverses the site’s functionality to achieve a specific goal. Not so much
the assertion of individual elements just for the sake of it, that’s more of a
unit level test. I feel that assertions of elements on the page should be
limited to ensuring those that are needed for the test are in place. I’ve seen
a pattern of testing for first and last items to load on the page or just
waiting for a document.Readystate is complete (1, 2).

Turning back to the main thrust of yesterday, here’s example
code for a pattern of declaring what we’re looking for then asserting we found
it.

There’s some extra bits in there like capturing a screen
shot but you’ll get the idea. I’m was quite happy with the pattern until I
tried it to find a Div, as mentioned above. The below code does NOT work in the
context I was trying it. When Writeline outputs what was returned for the value
of topNavClassName it comes back as OpenQA.Selenium.Firefox.FirefoxWebElement each
time. Clearly comparing that with a

{Console.WriteLine($"I found the main navigation Div by its Class Name: {topNavClassName}");

}else {Console.WriteLine("The main navigation Div was NOT located on the page");

var topBarNavigationException = $"I expected to find the main navigation Div of
'container-fluid', but instead I got {topNavClassName}";

TakeScreenshot.SaveScreenshot();

thrownewException(topBarNavigationException);

} }

I
also investigated if pulling the Class from the HTML might be a way forward (see
the commented out part of the code) but I hit the same issue. That issue being IWebElement
and a String can’t be compared so we have to tack on the ToString() on the end
of the line where we find the Class name. That way it’ll be accepted and the
solution can be built. But still, it comes back as OpenQA.Selenium.Firefox.FirefoxWebElement
each time.

We
can change the condition in the If statement from if (topNavClassName == expectedTopNavClassName)to if (topNavClassName != null)and we get a result. The
issue is I want to know what topNavClassName actually contains. Or do I? If I
change the name of the class is does fail, such as to ClassName("container-fluidsss").
So maybe that’s enough. It would be more reassuring to know what’s in there. Frustrating.