POV-Ray : Newsgroups : povray.off-topic : A curious perversion of the English language Server Time
1 Nov 2024 11:17:06 EDT (-0400)
  A curious perversion of the English language (Message 1 to 10 of 11)  
Goto Latest 10 Messages Next 1 Messages >>>
From: Orchid Win7 v1
Subject: A curious perversion of the English language
Date: 17 Jul 2013 16:32:31
Message: <51e6ff5f@news.povray.org>
For the past month and a half, I've been working on performing automated 
testing of our product. Now the product *already* has over one thousand 
unit tests, which test individual components of the application. But as 
any good tester will tell you, you also need integration tests to check 
that the pieces actually fit together correctly.

We do have a guy who's job is to test the software. But one human poking 
buttons at random to see if anything breaks is far slower and less 
systematic than an automated test system. (On the other hand, some tests 
cannot be automated - e.g., you can't write a test that checks that the 
text is legible, hasn't been cut off the edge of the page, etc.)

In short, I've build a system which allows me to remote-control the 
product over the network, and observe its responses. This allows me to 
control the software more or less the way a user would - click this 
button, select that option, check that the correct data is displayed.

I say "build a system" because, after many, many months of fruitless 
Google searching, we discovered that no such system already exists for 
our software platform. If it were a web application, there would be 
trillions of options for testing tools. If it were written in Qt, we 
would have several strong contenders to look at. But it's GTK+, so 
there's essentially nothing. We found a couple of OSS tools which were 
horribly broken, and that is all.

So I looked at the inner working of one of the tools, and ended up 
reimplementing it in C#. And I've spent a month putting all the 
functionality we need into it. Essentially I run my server code in the 
laptop I want to remote control, and run the client from inside Visual 
Studio on my development box. Then I run my test suite, and the tests 
talk to the client, which commands the server to do stuff.



Now, originally I wrote all the tests by hand. But more recently I've 
started using a curious creation known as SpecFlow. It's a tool for VS 
that lets you write user scenarios in "Gherkin", which is "a member of 
the Cucumber family of languages". (??!) For those of you who haven't 
heard, I will explain further...

Essentially, the idea is that you write a usage scenario in that looks 
like free-form English. For example, you might say

   Scenario: Adding a new user
     Given that I am on the User Admin page
     And there is currently no user named 'Tim'
     When I press the 'Add User' button
     And I type the username 'Tim'
     And I type the real name 'Timothy Robinson'
     And I press the 'Save' button
     Then there should now be a user named 'Tim'

You save this text in a file. You then right-click the file and say "run 
tests". The SpecFlow *generates code*, producing an NUnit test fixture - 
which is then run. Let me say that again: merely by writing the above 
text, a test has been created.

When you run the test, absolutely nothing happens. The test is merely 
marked as "inconclusive". Because, hey, the machine has no idea WTF 
you're talking about. What you have to do is go write a set of 
"bindings", which describe how to transform English into executable code.

If you've been paying attention, you'll have noticed that the above text 
isn't *really* free-form English at all. In fact, it's actually pretty 
rigidly structured. In fact, the format is line-based. Every line of 
text is a "test step". Each such line must begin with "Given", "When" or 
"Then". (Or "And", which duplicates the prefix from the previous line.)

The intention is that "Given" lines are test setup, "When" lines are 
test actions, and "Then" lines are test assertions. (Although you don't 
actually have to follow this, if you're feeling subversive.) What you do 
is you write C# code in methods, and you tag the methods with C# method 
attributes. For example,

    [When("I press the 'Save' button")]
    public void PressSave()
    {
      ...actual executable C# code...
    }

All SpecFlow actually does is look at each line of English text and then 
search the entire VS project (!!) for a method with a matching 
annotation. [It appears SpecFlow combines the English text into C# code, 
but the actual binding lookups happen at run-time.]

So in this way, all you're really doing is writing the test code 
manually, but writing a human-readable summary of what order the code is 
run in.



We began by having the testing guy write miles of SpecFlow scenarios, 
and then I go through them, press the "generate test steps" button, 
which builds a class full of empty step bindings. I then go through each 
method and fill it out with real code that really does something. In 
this way, the tester guy is like a script writer, and I'm the developer 
building the code that implements the tester's vision.

That worked for a while, but then I did what any self-respecting 
developer would do - I started to get lazy, and then I started to work 
smarter.

Firstly, I figured out that if you edit the test scenarios slightly so 
that every test is phrased *exactly* the same way, you can reuse any 
test steps you've already implemented. That can save you some coding. So 
by making minor grammatical changes to the written English, I could 
reduce the amount of code I need to write.

(Lots of scenarios are very similar, to the point that lots of them have 
clearly been copy-pasted multiple times. Either that or the guy make the 
exact same typo exactly the same way fifteen times in a row...)

Second, I noticed that as I wrote all the code, certain common patterns 
of commands popped up again and again. So I wrote a helper class which 
allows me to turn these into a single method call. (E.g., I might want 
to search for a button with a specific name, check that it's visible, 
check that it's enabled, and then click it. That can be made into one 
method call.)

That worked for a while. But then I started to get *really* sneaky. 
SpecFlow allows you to use regular expressions to actually PARSE STUFF 
OUT of test steps. For example,

    [When("I press the '(.*)' button")]
    public void PressButton(string name)
    {
      ...code...
    }

Once I implement the code, I now never, ever have to manually implement 
clicking a button again. Suddenly 60% of the test steps I'd been coding 
can now share this single step binding. In order words, my work just got 
60% easier (and my codebase 60% smaller).

After a while I managed to put together a library of bindings so 
comprehensive that for many of the scenarios that had been written, I 
could merely reword them very slightly and actually generate an entire, 
runnable, valid test WITHOUT WRITING ANY CODE! I could actually build by 
test suite just by rephrasing some English into broken robot-speak.

To see how far you can take this, consider the following example:

   Scenario: Adding a new user
     Given that I am on the User Admin page
     And the table does not contain a row with 'Tim' in the 'Username' 
column
     When I press the 'New User' button
     Then I should be on the Create User Page
     When I type 'Tim' in the Username field
     And I type 'Timothy Robinson' in the Real Name field
     And I select the 'Normal User' radio-button
     And I check the 'Accounting' check-box
     And I press the 'Save' button
     Then I should be on the User Admin page
     And the table should include the following rows:
       | Username | Real Name        | Account Type | Group Membership |
       | Tim      | Timothy Robinson | Normal       | Accounting       |

That final line has a binding where SpecFlow executes a method with a 
"table" as argument. The method actually queries the display, checks 
that the specified columns exist in the table, searches for a row where 
the Username column contains "Tim", and then checks that the other cells 
in that row contain the specified values. This method is *not* specific 
to the user admin page; it works for *any* page that has a single table 
on it. And it works for any number of rows, and it allows those rows to 
appear in any order. (For that matter, the columns may appear in any 
order, not necessarily the one shown. And there may be additional 
columns that we don't care about.)

In the one hand, this is a fairly crazy level of testing. On the other 
hand, this has slowly devolved away from being a high-level user-centric 
description of what the application should do, into a very low-level 
"check the exact status of every widget on the entire page according to 
that I, the application developer, what to test for". Look at the second 
line: we've gone from "there isn't a user named Tim" to "the table does 
not contain a row with Tim in the Username column".

Maybe I'm doing it wrong.



Eventually, I came across a system of features where the test scenarios 
become incredibly repetitive. But SpecFlow has an answer for this also. 
Observe:

   Scenario: Changing user type from Normal User to Super User
     Given that I am on the User Admin page
     And the table includes the following rows:
       | Username | Account Type |
       | Tim      | Normal       |
     When I select the row with 'Tim' in the 'Username' column
     And I press the 'Edit' button
     Then I should be on the Edit User page
     And the 'Username' field should contain 'Tim'
     And the 'Normal User' radio-button should be selected
     When I select the 'Super User' radio-button
     And I press the 'Save' button
     Then I should be on the User Admin page
     And the table should include the following rows:
       | Username | Account Type |
       | Tim      | SUPER USER   |
     When I select the row with 'Tim' in the 'Username' column
     And I press the 'Edit' button
     Then I should be on the Edit User page
     And the 'Super User' radio-button should be selected

This checks that when I change the user's type, the data actually saves, 
the table updates correctly, and when I recall the data it's still 
there. (You'd be surprised how often this fails for obscure properties 
that nobody really cares about...)

Now go write a test checking for all the other user types you can 
possible have. Yeah, that won't talk long; a few copy-paste operations 
later, and this gigantic monstrosity has been duplicated enough that if 
you never need to change it, you'll have to change it five times! o_O

So what do I do? I change it to this:

   Scenario Outline: Changing user type
     Given that I am on the User Admin page
     And the table has 'Tim' in the 'Username' column
     When I select the row with 'Tim' in the 'Username' column
     And I press the 'Edit' button
     Then I should be on the Edit User page
     And the 'Username' field should contain 'Tim'
     When I select the '<type button>' radio-button
     And I press the 'Save' button
     Then I should be on the User Admin page
     And the table should include the following rows:
       | Username | Account Type   |
       | Tim      | <type display> |
     When I select the row with 'Tim' in the 'Username' column
     And I press the 'Edit' button
     Then I should be on the Edit User page
     And the '<type button>' radio-button should be selected

     Examples:
       | type button | type name  |
       | Normal User | Normal     |
       | Supervisor  | Supervisor |
       | Manager     | Manager    |
       | Super User  | SUPER USER |

We now have a *parametrised* test script. SpecFlow takes my string 
template, instantiates it with the data from the table to generate 
psuedo-English, with the test bindings then dismantle back into data 
which they pass to the server to actually execute the tests. We have now 
come completely full circuit and disappeared up our own wotsits!

Look at that final line; SpecFlow replaces by variable with a value, 
which the step binding then uses a regex to parse back out so it can 
make the server call. (In fairness, you *can* write a template such that 
a different method gets called for each instance of the template...) 
Look at the vagueness of that parenthetical statement; you can't even 
tell which level of templating I'm talking about any more!

Now I am become death, the destroyer of worlds. All we need now is for 
SpecFlow to implement conditional branching and iteration, and it'll be 
Turing-complete. AND THEN THE WORLD IS NOT SAFE!!

The madness. The madness!!


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: A curious perversion of the English language
Date: 17 Jul 2013 16:37:39
Message: <51e70093$1@news.povray.org>
On 17/07/2013 09:32 PM, Orchid Win7 v1 wrote:
> Now I am become death, the destroyer of worlds. All we need now is for
> SpecFlow to implement conditional branching and iteration, and it'll be
> Turing-complete. AND THEN THE WORLD IS NOT SAFE!!
>
> The madness. The madness!!

...sorry about that. I'm back now.


Post a reply to this message

From: Nekar Xenos
Subject: Re: A curious perversion of the English language
Date: 17 Jul 2013 16:50:56
Message: <op.w0dv6517ufxv4h@xena>
On Wed, 17 Jul 2013 22:37:45 +0200, Orchid Win7 v1 <voi### [at] devnull> wrote:

> On 17/07/2013 09:32 PM, Orchid Win7 v1 wrote:
>> Now I am become death, the destroyer of worlds. All we need now is for
>> SpecFlow to implement conditional branching and iteration, and it'll be
>> Turing-complete. AND THEN THE WORLD IS NOT SAFE!!
>>
>> The madness. The madness!!
>
> ...sorry about that. I'm back now.

Create C+ interface that resembles SpecFlow's language...

.. but that would be a bit redundant.

-- 
-Nekar Xenos-


Post a reply to this message

From: Stephen
Subject: Re: A curious perversion of the English language
Date: 17 Jul 2013 16:56:58
Message: <51e7051a@news.povray.org>
On 17/07/2013 9:32 PM, Orchid Win7 v1 wrote:
> For the past month and a half, I've been working

[snip]

So, you are enjoying your new job, then?

Admit it. We were right, you were wasted in your old one.
Have you heard how your old workmates are getting on and has your father 
found a job yet?

-- 
Regards
     Stephen


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: A curious perversion of the English language
Date: 17 Jul 2013 17:20:18
Message: <51e70a92@news.povray.org>
On 17/07/2013 09:56 PM, Stephen wrote:
> So, you are enjoying your new job, then?

Yeah, at the moment it's OK. Sometimes I wish for a little more 
recognition - I just build an entire remote control framework, build a 
test framework on top of that, and then built a SpecFlow library on top 
of that, in addition to cleaning and implementing over 150 tests. I 
doubt anybody else in our office could have made this nice a job of 
it... but maybe I'm just deluding myself.

> Admit it. We were right, you were wasted in your old one.

Oh, I thought I admitted that a long time ago. The contention was 
whether I *could* get another job, not whether I *should*...

> Have you heard how your old workmates are getting on and has your father
> found a job yet?

My dad has a crap dead-end job that pays peanuts and involves an even 
worse commute than the last job. Then again, it beats being unemployed, 
so...


Post a reply to this message

From: Jim Henderson
Subject: Re: A curious perversion of the English language
Date: 18 Jul 2013 01:08:04
Message: <51e77834@news.povray.org>
On Wed, 17 Jul 2013 22:20:23 +0100, Orchid Win7 v1 wrote:

> On 17/07/2013 09:56 PM, Stephen wrote:
>> So, you are enjoying your new job, then?
> 
> Yeah, at the moment it's OK. Sometimes I wish for a little more
> recognition - I just build an entire remote control framework, build a
> test framework on top of that, and then built a SpecFlow library on top
> of that, in addition to cleaning and implementing over 150 tests. I
> doubt anybody else in our office could have made this nice a job of
> it... but maybe I'm just deluding myself.

I find that particularly in the IT and technical fields, recognition is 
difficult.  Many managers I've worked for even admitted that they sucked 
at it.

I don't think you're deluding yourself - the description you gave of what 
you've been working on is something I understand, but I only know a 
handful of people who could have done it.  Job well done, Andy.

>> Admit it. We were right, you were wasted in your old one.
> 
> Oh, I thought I admitted that a long time ago. The contention was
> whether I *could* get another job, not whether I *should*...

You managed it a few weeks after being laid off.  It took me 4 months to 
find something that is essentially part-time (and 2 years later, I'm 
still doing it).  I've just applied for a position at a very large 
software company, but we'll see how the interview process goes (it's a 
large enough company that you don't talk to their "recruiter community", 
you have a liaison that you work through for a few weeks.  That's a 
liaison to the *recruiters*, not to the hiring managers).

Jim


Post a reply to this message

From: scott
Subject: Re: A curious perversion of the English language
Date: 18 Jul 2013 03:22:16
Message: <51e797a8@news.povray.org>
> For the past month and a half, I've been working on performing automated
> testing of our product. Now the product *already* has over one thousand
> unit tests, which test individual components of the application. But as
> any good tester will tell you, you also need integration tests to check
> that the pieces actually fit together correctly.
>
> We do have a guy who's job is to test the software. But one human poking
> buttons at random to see if anything breaks is far slower and less
> systematic than an automated test system. (On the other hand, some tests
> cannot be automated - e.g., you can't write a test that checks that the
> text is legible, hasn't been cut off the edge of the page, etc.)
>
> In short, I've build a system which allows me to remote-control the
> product over the network, and observe its responses. This allows me to
> control the software more or less the way a user would - click this
> button, select that option, check that the correct data is displayed.
>
> I say "build a system" because, after many, many months of fruitless
> Google searching, we discovered that no such system already exists for
> our software platform. If it were a web application, there would be
> trillions of options for testing tools. If it were written in Qt, we
> would have several strong contenders to look at. But it's GTK+, so
> there's essentially nothing. We found a couple of OSS tools which were
> horribly broken, and that is all.
>
> So I looked at the inner working of one of the tools, and ended up
> reimplementing it in C#. And I've spent a month putting all the
> functionality we need into it. Essentially I run my server code in the
> laptop I want to remote control, and run the client from inside Visual
> Studio on my development box. Then I run my test suite, and the tests
> talk to the client, which commands the server to do stuff.

That's obviously totally impossible to actually implement, and there 
must be about one person in the entire world whose job it is to do stuff 
like that. :-)


Post a reply to this message

From: scott
Subject: Re: A curious perversion of the English language
Date: 18 Jul 2013 03:35:17
Message: <51e79ab5@news.povray.org>
> Now I am become death, the destroyer of worlds. All we need now is for
> SpecFlow to implement conditional branching and iteration, and it'll be
> Turing-complete. AND THEN THE WORLD IS NOT SAFE!!

...unless you reimplemented it all in Haskell :-)


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: A curious perversion of the English language
Date: 18 Jul 2013 03:54:01
Message: <51e79f19$1@news.povray.org>
On 18/07/2013 08:35 AM, scott wrote:
>> Now I am become death, the destroyer of worlds. All we need now is for
>> SpecFlow to implement conditional branching and iteration, and it'll be
>> Turing-complete. AND THEN THE WORLD IS NOT SAFE!!
>
> ...unless you reimplemented it all in Haskell :-)

You laugh, but that's not so implausible. In fact, I posit that the 
hardest part would be turning it into a VS plugin... actually parsing 
Gherkin and generating code from it should be trivial for just about any 
programming language. (Except Bash, because that isn't a real 
programming language...)


Post a reply to this message

From: Jim Henderson
Subject: Re: A curious perversion of the English language
Date: 18 Jul 2013 15:49:39
Message: <51e846d3$1@news.povray.org>
On Thu, 18 Jul 2013 08:22:15 +0100, scott wrote:

> That's obviously totally impossible to actually implement, and there
> must be about one person in the entire world whose job it is to do stuff
> like that. :-)

Damn, now I need a new keyboard ;)

Jim


Post a reply to this message

Goto Latest 10 Messages Next 1 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.