Using SpecFlow Featurs as subroutines in other features - specflow

I may have this completely wrong, but I've been searching available documentation and googling for 2 weeks now, and have my head completely wrapped around the axle.
I am trying to use SpecFlow to write a regression test for our site. This means that I want to exercise all the features so that if we inadvertently broke something, it will catch it.
The site is basically an incident reporting portal. The home page has about 50 different buttons, each of which opens up the data entry pages for a different class of incident.
The data entry pages are arranged in a "wizard" fashion, where it starts with a page of general questions, then moves on to a page of more specific questions and so on. The questions are more or less grouped in the classic "who/what/when/where/why" grouping, with one wizard page for each group, so that we don't overwhelm the user with 100 questions presented all at once.
Exactly which pages are needed depends on the particular type of incident. Some incident types have as many as 8 pages, some as few as 3.
Our specifications for each page are framed in BDD style - Given/When/Then. So it is very natural to translate those specifications into SpecFlow features, and I have done that, at least for the first page of general information questions. But the Scenario had about 30+ steps in it.
I have also written another Feature for testing from the home page -
Given I'm logged in on the home page
When I clicked the button for XYZ ticket
Then it opens XYZ ticket
And the General Information page is displayed.
And I can drive that scenario from a table so that I can test as many different incident types as I want.
So far so good.
But now I want to add
And the General Information page requirements are verified
Where the step definition for that last clause would run the whole scenario for the general information page. In other words, I want to use that other scenario that I have written as a subroutine in this one.
(And then I want to go on and do the same for each of the other wizard pages. But let's get the first one first!)
I can't figure out a way to do that. I tried writing the step definition for the above clause to invoke the step definitions of the General Information scenario, e.g.
Given("I am on the General Information page")
When ("I click this checkbox")
Then ("This happens")
You used to be able to do that (although that would still be a lot of repetition). But now that's giving a warning message that function is deprecated and will be removed (and since I've now upgraded, it may already have been removed - I haven't tried it since I upgraded.) The github issues page (https://github.com/SpecFlowOSS/SpecFlow/issues/1733 has a lot of discussion on it, none of which sheds any light on how to do what I'm trying to do. The primary author (SabotageAndi) seemed to be saying "That's a bad thing; don't do that" without really giving any alternative, at least none that I was able to understand.
Can anyone give me a direction for how to accomplish what I'm trying to do?

I want to use that other scenario that I have written as a subroutine
in this one.
You can't reuse scenarios defined in feature files.
The best you can do is create a new Step that reuse already defined steps by calling them direcly (jameswtelfer comment on 31 Jan in github issue you provide).

Related

Is there a way to show commits on subtasks of stories in a Jira scrum board?

We are migrating from an in-house tool to Jira for managing our scrum board, and we have concerns that I have been unable to resolve by searching the Internet. But you folks are smart, right? ;-)
Our current scrum board shows the usual swim lanes across state columns (for todo, progress, review, done). Each swim lane represents a user story, and has a link to (and a snippet of) the user story description in Jira. It also has a number of 'tickets' (these would be subtasks in Jira lingo) that start in 'todo' and move across to eventually end up in 'done'.
So far, Jira can do all of this, too (although creating sub-tasks is rather a lot more work in Jira than in our in-house tool). However:
When we commit code, we include a ticket ID in the commit message, and thus each ticket displays a list of commits that were done to complete that particular ticket / partial story. I haven't been able to find out how to do this in Jira -- if it's possible at all. Instead, it seems one must open a sub-task to see if there are any commits on it?
Each commit also shows its review state, which gives us an excellent overview of how close to done a ticket really is. I haven't been able to find out how to do this in Jira -- if it's possible at all. Instead, it seems one must open the sub-task, and drill down further into Fisheye(?) in order to see the review state?
In total, our tool provides a one-screen overview of the state of each user story, ticket, commit, and review state; and it's very lightweight to pull in new stories (from Jira) and add tickets. We fear that Jira is not able to provide such a one-screen overview, forcing us to open Fisheye in order to know whether a given commit has passed review.
Is it really true that Jira must be this cumbersome?
For reference, here is what a single ticket (subtask) looks like in our system:
And if you look at the whole scrum board, it's actually quite easy to get a feel for the number of commits on individual user stories and tickets, and the ratio of pending/passed/failed code reviews:
I agree with your fears when you say
We fear that Jira is not able to provide such a one-screen overview
In my experience (7+ years with Jira/Agile) I've not seen a such condensed view of information about a sigle user story even on a swimlane with relative cards.
Also in the Atlassian marketplace there seems to be no good plugin to solve your issue, even partially.
To make such move from your in-house tool to Jira retaining all you have there, I fear you should develop a custom Plug-in using Jira SDK to integrate with the agile boards.
It may be enough to start by developing a custom field to show what you need from a "ticket" (ie sub-issue) and trying to insert it into one of the three "slots" available for cards (I mean Rapidboard card layout configuration screen).
If you wanna try, start from here.
Another option to create a new custom field would be the Adaptavist Scriptrunner plugin. It will ease the building of custom fields: your new field can be written also in Groovy rather than plain Java. I've used it to build an extended status custom field (just to give the user an immediate big picture of it) that informs him in plain english and with stylish css colors why an issue is blocked or anything else relevant, getting data from other fields or linked issues that are not immediately visible to the user. IMHO, it is very similar to your problem.

Disable multi-tab browsing for single session/user

[Disclaimer: I'm not sure if this kind of question is accepted here as it is about a piece of software deployed already. Rest assured I didn't drop any confidential information. Also do tell me if I violated any rules in SO by posting this so I can take it down immediately]
I have a working Learning Management System web application and I recently received a bug report about a button not showing. After investigating, I have proved that the user was not using the web app as intended. When taking an exam, he was opening multiple tabs to exploit the feature that informs him whether the answer was correct or not. He then will use this information to eliminate the wrong answers and submit all the right answers in another tab/window.
I'm using Rails 4.2. Is there a way to prevent multi-tab browsing? I'm thinking like if a user is signed in and he attempted to open a new tab of the webapp, he should see something like "Please use one tab" and all the features/hyperlinks/buttons are disabled.
Here's a screenshot of how I proved he was using multiple tabs. Notice that there are multiple logs of the same attempt # because the current implementation allows saving a study session and resuming later (this is the part that's exploited). The opening of multiple tabs searches for the most recent attempt session and continues from there. This is also the reason why most of the sessions don't have a duration value -- the user only finishes a study session for one tab (by clicking a button that ends the study session). The system cannot compute for the duration because the other sessions don't have an end timestamp.
-
This is what a single-tab user looks like:
This is more of an application misuse issue more than a bug.
You should add protection not only from multi tab, but for multi browsers aw well, so it can't be purely FrontEnd check.
One of the solutions could be using ActionCable to check if a user has an active connection already and then act accordingly.
Another, for example, generate a GUID in JS and pass it with every answer. If its different from previous answer, it means user opened a new window.
But of course the solution would depend on your current architecture, without knowing how do you currently organise client-server communication it's hard to give exact and optimal solution.
I found an answer here. I just placed this js in the application view to prevent any extra instance of the website.
Thanks for everyone who pitched in.

Check Site URL which fills data in Report Suite in SiteCatalyst (Omniture)

This question may seems odd but we have a slight mixup within our Report Suites on Omniture (SiteCatalyst). Multiple Report Suites are generating analytics and it's hard for us to find which site URL is constituting the results.
Hence my question is, is there any way we can find which Site is filling data within a certain Report Suite.
Through this following JS, I am able to find which "report suite" is being used by a certain site though:-
javascript:void(window.open("","dp_debugger","width=600,height=600,location=0,menubar=0,status=1,toolbar=0,resizable=1,scrollbars=1").document.write("<script language=\"JavaScript\" id=dbg src=\"https://www.adobetag.com/d1/digitalpulsedebugger/live/DPD.js\"></"+"script>"));
But I am hoping to find the other way around that where Report Suite gets its data from within the SiteCatalyst admin.
Any assistance?
Thanks
Adobe Analytics (formerly SiteCatalyst) does not have anything native or built in to globally look at all data coming to see which page/site is sending data to which report suite. However, you can contact Adobe ClientCare and request raw hit logs for a date range, and you can parse those logs yourself, if you really want.
Alternatively, if you have Data Warehouse access, you can export urls and domains from there for a given date range. You can only select one report suite at a time but that's also better than nothing, if you really need the historical data now.
Another alternative is if your sites are NOT currently setting s.pageName, then you may be in some measure of luck for your historical data. The pages report is popped from s.pageName value. If you do not set that variable, it will default to the URL of the web page that made the request. So, at a minimum you will be able to see your URLs in that report right now, so that should help you out. And if you define "site" as equivalent of "domain" (location.hostname) you can also setup a classification level for pages for domain and then use the Classification Rule Builder and a regular expression to pop the classification with the domain, which will give you some aggregated numbers.
Some suggestions moving forward...
I good strategy moving forward is to have all of your sites report to a global report suite. Then, you can have each site also send data to a site level report suite (warning: make sure you have enough server calls in your contract to cover this, since AA does not have unlimited server calls). Alternatively, you can stick with one global report suite and setup segments for each site. Another alternative is to create a rollup report suite to have all data from your other report suites to also go to. Rollup report suites do not have as many features as standard report suites, but for basic things such as pages, page views, it works.
The overall point though is that one way or the other, you should have all of your data go into one report suite as the first step.
Then, you should also assign a few custom variables to be output on the pages of all your sites. These are the 4 main things I always try to include in an implementation to make it easier to find out which sites/pages are reporting to what.
A custom variable to identify the site. Some people use s.server for this. However, you may also want to pop a prop or eVar with the value as well, depending on how you'd like to be able to break data down. The big question here is: How do you define "site" ? I have seen it defined many different ways.
If you do NOT define "site" as domain (e.g. location.hostname) then I suggest you pop a prop and eVar with the domain, because AA does not have a native report for this. But if you do, then you can skip this, since it's same thing as point #1
A custom prop and eVar with the report suites(s). Unless you have a super old version of legacy code, just set it with s.sa(). This will ensure you get the final report suite(s), in case you happen to use a version that uses Dynamic Account variables (e.g. s.dynamicAccountList).
If you set s.pageName with a custom value, then I suggest you pop a prop and eVar with the URL. Tip: to save on request url length to AA, you can use dynamic variable syntax to copy the g parameter already in a given AA request. For example (assuming you don't have code that changes the dynamic variable prefix): s.prop1='D=g'; Or, you can pop this with a processing rule if you have the access.
you can normally find this sort of information in the Site Content-> Servers report. There will be information in there the indicates what sites are sending in the hits. Your milage may vary based on the actual tagging implementation, it is not common for anyone to explicitly set the server, so the implicit value is the domain the hit is coming in from.
Thanks C.

How do describe a simple process in Gherkin-style? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Suppose I'm designing some SaaS service. And I need to have a function that allow users create sites. User can makes special settings for each site in the admin panel (e.g. design of widget) and gets unique code for install service to his own site.
User story could be:
As a logged user I want to add the new site in the admin panel so that I could configure each instance of widgets separately and could get a unique code for install widget to my own site.
Form
But if I will try to describe this functionality with BDD or GWT (Given When Then) or Gherkin-style, I will face with some trouble. I start from next description:
GIVEN I'm logged into admin panel
AND I'm on "Sites" page
WHEN I click "Add site" button
THEN Pop-up window "Add site" come up
As you can see above realization suppose that site adding will be in pop-up window (e.g. it very important for UX). Pop-up window contains Site URL input field, drop-down control with languages and "Add" and "Cancel" buttons.
And we got a strange scenario which responsible for just pop-up opening. Is it correct? And how can I name this scenario ("Add site's form opening" ??)? Also this scenario has only a one case (when I click - pop-up open). Maybe this scenario not needed at all? I'm confused...
In this case we need to create another scenario when describes:
GIVEN "Add site" pop-up form is opened
WHEN I fill the "Site URL" field
AND click on "Add" button
THEN New site will be create in system
AND I will transfer to my own site's list
How do you think, where do I need to apply a business rules such as:
1) When new site is created a unique code must be generated and consist of minimum 8 characters including numbers and Alphabetical symbols.
2) checks doesn't apply for Site URL input field and user can input a Cyrillic symbols
3) etc?
I have a lot of additional question and hope on the community help!
The thing with BDD is to stay away from implementation details as much as possible. This scenario has multiple implementation details:
GIVEN I'm logged into admin panel AND I'm on "Sites" page
WHEN I click "Add site" button
THEN Pop-up window "Add site" come up
What happens if the "Sites" page becomes "Awesome Site" page or is simply deleted?
What happens if "Add site" is not a button anymore?
What happens if it's not a popup but a redirect occuring
What happens after? Is the value simply in showing the popup? I guess not...
For this specific example, a better approach would be:
GIVEN I'm an authorised administrator
WHEN I enter all the required information for a new site and save it
THEN I should see that site in my own sites list
With this scenario, if your implementation changes, you will only have to change your step definitions, you won't have to change your gherkin. Don't forget that those tests are supposed to explain the Behaviour of the system, not the way it is implemented.
The other questions you have are more related to unit testing in my opinion:
When new site is created a unique code must be generated and
consist of minimum 8 characters including numbers and Alphabetical
symbols => I'd do it at the class level, gherkin would not be
appropriate unless the customer specifically asked for this, then
the condition is "THEN a code having the required characteristics is
generated for that site" and you would have to define "required
characteristics" in a glossary the customer can read and understand.
Checks doesn't apply for Site URL input field and user can input a Cyrillic symbols => again, would put that at the class level en same as for 1. unless the customer wants to be able to read something about it, it should be at the unit level.
I hope that answers your question. I recommend this article by Dan North if you want to have a better idea of how to write better gherkin features.
EDIT 11/13/14
Based on your comments, I suggest we take a step back and describe a way to deal with requirements in your case. I have to tell you that I'm not a BDD expert and am only sharing my own personal experience, for more info on the subject I suggest you get in touch with the guys behind BDD Kickstart and Cucumber.pro where you will find online BDD courses. They will be able to give you lots of information and books to read.
That being said, let's dive into the subject.
The first thing you get is a list of features or stories that, if you follow Mike Cohn's story template would look like:
As a <type of user> I want <to do something> in order to <serve a business purpose>
I personally like to put the business purpose first to make sure we don't skip it in the discussions. You might also not follow that template and that's fine, but remember that it's a good idea to make sure the features you are listing with your customers have a business purpose. If there is no business value behind a feature then what's the point of doing it anyway...
So you do have a list of features/stories described as above. Now for each of these features, there are different cases or scenarios, that's what Dan describes in his article. This is where the Given-When-Then is introduced.
Scenario: Title
Given <some context>
When <there is an event>
Then <something happens>
Each of those scenarios are examples on how this specific feature behaves in different contexts. They are the different acceptance criteria for a specific feature, things the customer described as the expected behaviour of the system. They should be ignorant of any implementation details. So stuff like:
Given I am on page "First page"
When I click "Hello world"
Then I should see "You clicked hello world"
Is wrong for the reasons described prior to this edit.
Let's assume the following feature:
In order to save time when answering clients requests, as a webmaster,
I want to be able to manage the list of websites I am responsible for
Scenarios for this story would be:
Scenario 1: Show a list of websites
GIVEN I am an authorised administrator
AND I am managing several websites
THEN I should see a list of all the sites I manage
Scenario 2: Add website to list
GIVEN I am an authorised administrator
WHEN I enter all the required information for a new site and save it
THEN I should see that site in my own sites list
Scenario 3: Edit website from list
GIVEN I am an authorised administrator
WHEN I edit the site informations
THEN I the changes should be visible in my sites list
...
Now what if you want to go into data validation stuff like "site should have a title" for instance. To me there are two different ways to approach this. You can test that from the user's perspective with a full-stack test or test that there is some validation at the object level.
Let's assume the following scenario:
Scenario: New site has no title
GIVEN I'm an authorised administrator
WHEN I forget to fill in the title for a new site and save it
THEN I should be warned the site is not valid
You can use cucumber or specflow to run this scenario from the UX, therefore using some kind of browse-based proxy to test your app. That is usually slow as it hits the whole system and simulates a real user. It's an option, but I don't think it's the best though. IMO not all tests should be run against the UX and having too many Gherkin features can be a pain to maintain, that's why I prefer focusing on having the happy or critical path (usually I ask myself, where does the money comes from) tested full-stack and put the rest at lower levels.
You can still use Gherkin for these unit tests if you'd like. But that is not mandatory. You only need a way to show your customer you actually have a test for all those specific format controls and validation checks.
That doesn't mean you are not doing BDD anymore, you can still use the given-when-then-should pattern in rspec if you're a rubyist, or any other testing framework you use.
Hope that clarifies all this, let me know if there are any confusing parts...
I think Marc simply deserves the big green tick on this one, thanks to his amazingly thorough answer!
I just wanted to add a few comments.
You don't need to automate all your scenarios.
If you want to capture business requirements in a form that everyone (i.e. including non-tech savvy folks) can understand and Gherkin's Given/When/Then work for you, just go for it. There's nothing forcing you to automate all of your scenarios.
You don't need to automate all your scenarios through the UI.
Your software is made of layers that often respond to similar behaviours, via different interfaces (UI, HTTP, API, ...). Should you want to describe fine-grained business rules (i.e. site name constraints) with automated gherkin scenarios, you could write step definitions that talk directly to your domain layer instead of going through the user interface. That would probably still give you a decent level of confidence.
As a side note, I would recommend not to use Given/When/Then in classic testing frameworks (i.e. those that only devs can see!) if your purpose is to share your tests/requirements with non-tech people.
Have conversations!
Above all, BDD is about better communication: try to talk more, involve your developers (or some of them) earlier in the process so that they gain more knowledge, sooner. Formalising Gherkin scenarios comes in a second phase. Automating them should even be further down your priority list!

Persisting data in MVC for the duration of a users session

Apologies in advance as I'm sure this topic has no doubt been asked before but I couldn't find any post that answers my specific query.
Bearing in mind that I'm new to MVC this is where I have got to. I've got a project developed under VS 2010 using the MVC 3 framework. I've got a search page which consists of 6 fields and a nested model which itself holds around 3 fields.
I can successfully post all this data back to itself and the data is successfully passed as a model and back agian so the fields keep the data which the user has supplied.
Before I move on to actually using this search criteria on another view a thought hit me. I want to keep this search criteria, and possibly even the search results in memory for the duration of the users session.
The reasoning behind this is simply to save my users time by:
a) negating the need to keep re-inputting their search criteria regardless of how they enter or leave the search page
b) speed up the user experience by presenting the search results more quickly
The later isn't as important as the first requirement.
I've done some google searches and indeed had a look through this site on similar topics. From what I've read using sessions (which I would typically use if developing a PHP site) is a no no. From the reasons I've read as to why you shouldn't use sessions seem valid and I'm happy to go along with it.
But now I'm left in a place where I'm scratching my head wondering to myself what exactly is best practice to achieve this simple goal that could be applied to similar situations later down the line in the project.
I also looked at the OutputCache method and that didn't behave as I expected it to. In a test I set the timeout for 30 seconds. After submitting a search I clicked the link to my search page to see if the fields would auto-populate, they didn't. But then clicking the search button the values in the cache were retrieved. I thought I was making progress but when I tried to submit a new value the old value from the cache came back i.e. I couldn't actually change my search criteria with the cache enforced. So I've discounted this as an avenue to explore.
The last option seems to suggest the use of cookies as the most likely candidate, but rightly or wrongly I feel this isn't the best solution. I would have thought the MVC 3 design pattern would have an easier and recommended method of persisting values. I'm sure there is but I've just not discovered it yet.
I have started to use JQuery and again this has been mentioned but I'm not sure this is right direction to take either.
So in summary my question really comes down to what is considered by the wider community as best practice for persisting data in my situation. Effiency, scalability and resiliancy is paramount as I'll have a large global user base that will end up using this web app.
Thanks in advance!
Pete
I'd just use cookies. They're simple to use, you can persist them for as long as you want or have them expire when the users closes their browser, and it doesn't sound like you are storing anything sensitive in them.

Resources