We are employing BDD and using SpecFlow to drive our development (ATDD).
Our QA team would like to define their own 'end-to-end regression tests (in Gherkin/SpecFlow) and re-use the Steps we have already defined.
(Please note - I know that this is not a great example but it should provide enough details)
A test may include..
Log in
Search for a product
Select a product to buy
Create an order
Select delivery option.
Submit the order.
Cancel the order.
This would suggests a scenario like..
Given I am logged in
When I Search for a product
And I Select a product to buy
And I Create an order
And I Select delivery option
And I Submit the order
And I Cancel the order
Then ??!!
Which is clearly wrong as we are not checking the output at each step.
So this may be resolved as a sequence of scenarios:
Scenario 1:
Given I am logged in
When I Search for a product
Then I see a list of products
Scenario 2:
When I select a product to buy
Then I can create an order
Scenario 3:
When I create the order
And I Select delivery option
Then I can submit the order
etc etc
The main issue with this is that there seems no way to specify the order/sequence that the scenarios are run in (a characteristic of nUnit?). Because there are dependencies between scenarios (they are not set to a know starting point) they must be run in sequence.
My questions are:
a) Are we trying to fit a square peg in a round hole?!
b) Does anyone know if there is a way to use SpecFlow/Gherkin in this way?
c) Or does anyone know what alternatives there are?
Many thanks!
I would say that you are writing your scenarios on the wrong abstraction level. But that depends on what you want to use them for;
If you want to write test-scripts then you are on the right track... but it will be a nightmare to maintain as it, in the first case (long script) will be very brittle and the second case (several scenarios) need to ensure a certain execution order. Both of them are discouraged and considered anti-patterns.
I would suggest that you merge the ATDD-tests you are writing and talk to the test department to get their view on the matter and include the test-cases they need to ensure that the system is thoroughly tested. Who know? You might even learn something from each other :P
And when you write those "specifications" (as I rather call them) you write them on a higher level. So instead of writing:
Given I am logged in
When I Search for a product
And I Select a product to buy
And I Create an order
And I Select delivery option
And I Submit the order
you write something like
When I submit an order for product 'Canned beans'
In the step-definitions behind that step you perform all that automation (login, browsing to the product page, select the delivery options, submit the order).
All of this can be read about in these great articles on how to write maintainable UI Automation tests:
http://gojko.net/2010/04/13/how-to-implement-ui-testing-without-shooting-yourself-in-the-foot-2/
http://elabs.se/blog/15-you-re-cuking-it-wrong
http://www.marcusoft.net/2011/04/clean-up-your-stepsuse-page-objects-in.html
http://dhemery.com/pdf/writing_maintainable_automated_acceptance_tests.pdf
http://gojko.net/2010/01/05/bdd-in-net-with-cucumber-part-3-scenario-outlines-and-tabular-templates/
http://chrismdp.github.com/2011/09/layers-of-abstraction-writing-great-cucumber-code/
http://benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-in-user-stories.html
http://mislav.uniqpath.com/2010/09/cuking-it-right/
I hope this helps
Related
I am new to Google App maker and I don't have a lot of experience with coding either (sorry :/). Since App maker is marked as low-coding app builder tool, I assumed it was not that hard to make a very simple app with it. However, for me it is.
I need to make a simple app for demonstrations purposes only (so Cloud SQL and other complex database solutions are not in my interest here). I want to make it using calculated models (correct me if I am wrong, calculated models are just temporary solutions, since apps need to have like real databases to be fully functional?).
My app is basically made of 2 datas: 1) Employees and 2) Departments
-> Fields for "Employees" are: First name, Last name and Department.
-> Field for "Departments" is just Department name.
My app is supposed to look like this:
1st page: Table with current employees that has a button to add new employee,
2st page: Table with all department names (e.g. marketing, finance...) that has a button to add new department name,
3rd page: Form that opens when I click on add new employee button in which I can insert their first name, last name and from drop down menu choose department,
4th page: Form that opens when I click on add new department button in which I can insert new department name.
5th page: Form (or some other widget, not sure here) that has option to insert first and last name in order to find out what department that employee is assigned to.
I tried to make first 4 pages, but I end up with forms that I cannot insert anything into them. 5th page is still too much for me.
I hope you understand my struggles and if you know how to do it please share your knowledge. Thank you very much!
Calculated models are kind of like SQL views - they are not necessarily for temporary solutions. Every time you load a calculated model the script you write under that model's datasource is ran. That script usually loads data from an external source (I.e. grabbing stock prices from an API, loading data from an external SQL server, or generating random placeholder data).
You could use the cloud SQL models for this application that you are building - your table with all department names that is supposed to be displayed in the second page could just be a cloud SQL table with one single field for a department name.
I suggest you work through the example apps so you can get a better understanding of how the different components work. Here is a link to one for you to get started.
In short, you're going to create a few models to store information (I suggest using cloud SQL as the calculated models will require code whereas cloud SQL is more plug and play through app maker's bindings). Before you create any pages try to lay out how your databases will look as that will dictate how you set bindings or program your scripts.
Asking to completely make what is essentially a combination of the tutorials already provided by Google is pretty counter intuitive - you should ask more specific questions in regards to implementation.
As for App Maker being a low-code environment, that's only partially true. For very, very simple apps (think glorified forms) you will need only a couple lines of code and can probably do everything through drag-and-drop. However, anything more complicated than a simple form will almost certainly require a good chunk of actual code. There are plenty of resources online to learn Javascript.
You might want to try a google partner like AppSynergy for building stuff like this. It might be overkil for what you need (or maybe not if you intend to build a lot more stuff).
Is it possible to assign a person or a group of people as reviewers in a certain state of a workflow in Plone?
I have been looking at AutoRole en the IRolesplugin, but do not seem to find what I need?
In our case, users need a multiple review step workflow, yet the first reviewer should have control over which reviewers come afterwards...
Workflows can trigger scripts. Scripts can do things like grant roles to users. You'd have to come up with an approach to letting your first specify additional users. There are probably multiple ways to do it, but I could imagine using archetypes.schemextender or a custom content type to provide a field for choosing additional reviewers, only visible to initial reviewers. Then use those values in the workflow script. http://plone.org/documentation/kb/creating-workflows-in-plone/tutorial-all-pages provides a good overview of how DCWorkflow works.
I feel like I am fighting against the current when I develop ASP.NET Webform apps. I frequently run into the same problems, and while I eventually find some kind of workaround i'm never fully satisfied with the results.
Here is an example of a typical problem:
The design requires a grid or grid-like result set. This result set is pulled from a database, however, there are additional controls on each row that are not data bound, but their contents are used to insert data into other records.
A good example of this would be displaying a list of products, then adding selected products to a shopping cart based on values entered into quantity fields, and options selected per product. Throw into the mix that you have to allow multiple lines to be added to the cart at the same time, and it starts to get more complex.
Let's add to that mix that you can't select certain products together (mutually exclusive), that you can only select a certain number of one product, but not another, that prices may change while the user is selecting their items, that you you get an overall discount per item based on quantity purchased (both per item and overall order), that you are using a line of credit and cannot exceed the line of credit, nor can you buy more of a given item than an arbitrary amount set in your account or in the product by your account representitive (think certain over the counter medications that the government limits how many you can buy), etc.. etc.. etc..
What starts out as a simple grid with an add to cart becomes a hopeless mess of business logic, which then of course requires validation and notification to the user of various errors in their choices.
How does one deal with very complex data entry schemes in asp.net? How do you even begin to design a piece of software to do all this?
EDIT:
Please don't suggest changing the interface, as the interface is not the problem. Users are fine with it, and they demand that it function the way it does. I'm looking for help on how to design and solve the problem of implementing it.
Don't put anything other than the basic validation in your code behind. The code behind should just take what the user entered, build a business object (or collection of business objects) and let those business objects validate themselves.
Each business rule should be a single function call on the business object that deals with just the one rule and nothing else. You then simply call them one after another and keep track of which ones pass and which ones fail.
When a validation fails, the business objects can provide the code behind enough information that it can display the correct errors and highlight the fields that have errors.
Some options to consider:
Separate out your validation logic so you can call it from both client-side and server-side code (enables next point).
Use AJAX to perform server-side validation and provide immediate feedback as the user performs various tasks, ie increases quantity.
Provide abundant and clear instructions/feedback to the user both before and after any actions are performed. Before: warn that product X can't be bought with product Y (especially if Y is already in the cart). After: explain the problem exactly and suggest ways to correct, eg "why don't you remove product Y?")
Fail gracefully, ie if only one product fails validation then ensure all other products are added.
Simplify the entry process, eg only allow one product to be added to the cart at a time.
The last point is important. A complicated data entry process can confuse users before they start, and makes trying to understand the numerous validation errors difficult. And this is even before you start coding the validation logic.
I'm looking at accepting a project that would require me to clean up an existing e-commerce website. Its been relatively successful and has over 100,000 individual products - loaded both by the client and its publishers.
The site wasn't originally designed for this many products and has become fairly disorganized.
SO, the client has asked I look at a more robust search option - filterable and so forth. I completely agree it needs to be improved, but after looking at the database, I can tell that there are dozens and dozens of categories and not everything is labeled correctly etc.
Is there any database management software that could help me clean up 100,000 entries quickly? Make categories consistent - fix uppercase/lowercase problems etc.
Are there any companies out there that I can source just this particular part of the project to?
Its a massive amount of data-entry. If I spent 2 minutes per product, it would take me 6 months full time to just to complete the database cleanup. I either need to get it down to a matter of seconds per product or find a company that specializes in this type of work.
I don't even know what to search for on Google.
Thanks guys!
--
Thanks everyone for your ideas! I have a lot of options now so I feel a lot more comfortable heading in to this project. Right now I think the direction we will go is to build a tool that allows the client to hire data entry people that can update it as necessary. Then I will work as a consultant, taking care of any UPDATE-WHERE type functions as necessary.
Thanks again!
If there are inconsistencies like you are describing, it sounds like the problem may be more an issues of a bad data model (i.e. lack of normalization) than just dirty data. If good normalization is in place, cleaning up categories should be as simple as updating a single record per each category - but if category name is used instead of a foreign key, then you will most likely need to perform a series of UPDATE WHERE statements to clean up the text.
You may want to look into an ETL (extract, transform, load) tool that can help with bulk data transformation. I'm not familiar with ETL tools for mysql, but I'm sure they exist. SQL Server has a build in service called SQL Integration Services that provides the ability to extract data from an existing data source, perform bulk changes or transformations, and then reload the data back into a destination database. Tools like this may help speed up the process of standardizing capitalization, punctuation, changing categories etc.
Even still, don't overlook the possibility that the data model may need tweaking to help prevent this type of situation in the future.
Edit: Wikipedia has a list of opensource ETL products that you may want to investigate.
In any case you'll probability need to do more than "clean the data", which means you'll need to build new normalized tables. So start there, build a new database that is fully normalized, import the data "as is", with all the duplicate categories, etc.
for example, new tables:
Items
ItemID int identity/auto number
ItemName string
CategoryID int
....
Categories
CategoryID int identity/auto number
CategoryName string
....
import the bad data into the new system:
Items
ItemID ItemName CategoryID
1 thing A 1
2 thing B 2
3 thing C 3
4 thing D 1
Categories
CategoryID CategoryName
1 Game
2 food
3 games
now, you can consolidate the data using the PKs
UPDATE Items
SET CategoryID=1
WHERE CategoryID=3
DELETE Categories
WHERE CategoryID=3
You might just write an application where the customer can do the consolidation. Let them select the duplicates on a screen and merge to a selected parent category. you have this application do the merge sql from above.
If there are issues of needing to have a clean cut over date, create an application that generates a series of "Map" tables, where you store the CategoryNameOld="games" and the CategoryNameNew="Game" and use these when you do the conversion/load of the bad data into the new system's tables.
I would implement the new search system or whatever and build them a tool that would allow them to easily go through and cleanup the listings, re-categorize, etc. This task requires domain knowledge, so they're the best ones to do it.
Do some number crunching so they can prioritize the list and clean in order of importance.
Keep in mind that one or your options is to build a crappy interface that somebody can use to edit records, hire half a dozen data-entry people from a temp agency, spend two days training them, and let them go to town.
I've been playing with RSS feeds this week, and for my next trick I want to build one for our internal application log. We have a centralized database table that our myriad batch and intranet apps use for posting log messages. I want to create an RSS feed off of this table, but I'm not sure how to handle the volume- there could be hundreds of entries per day even on a normal day. An exceptional make-you-want-to-quit kind of day might see a few thousand. Any thoughts?
I would make the feed a static file (you can easily serve thousands of these), regenerated periodically. Then you have a much broader choice, because it doesn't have to run below second, it can run even minutes. And users still get perfect download speed and reasonable update speed.
If you are building a system with notifications that must not be missed, then a pub-sub mechanism (using XMPP, one of the other protocols supported by ApacheMQ, or something similar) will be more suitable that a syndication mechanism. You need some measure of coupling between the system that is generating the notifications and ones that are consuming them, to ensure that consumers don't miss notifications.
(You can do this using RSS or Atom as a transport format, but it's probably not a common use case; you'd need to vary the notifications shown based on the consumer and which notifications it has previously seen.)
I'd split up the feeds as much as possible and let users recombine them as desired. If I were doing it I'd probably think about using Django and the syndication framework.
Django's models could probably handle representing the data structure of the tables you care about.
You could have a URL that catches everything, like: r'/rss/(?(\w*?)/)+' (I think that might work, but I can't test it now so it might not be perfect).
That way you could use URLs like (edited to cancel the auto-linking of example URLs):
http:// feedserver/rss/batch-file-output/
http:// feedserver/rss/support-tickets/
http:// feedserver/rss/batch-file-output/support-tickets/ (both of the first two combined into one)
Then in the view:
def get_batch_file_messages():
# Grab all the recent batch files messages here.
# Maybe cache the result and only regenerate every so often.
# Other feed functions here.
feed_mapping = { 'batch-file-output': get_batch_file_messages, }
def rss(request, *args):
items_to_display = []
for feed in args:
items_to_display += feed_mapping[feed]()
# Processing/returning the feed.
Having individual, chainable feeds means that users can subscribe to one feed at a time, or merge the ones they care about into one larger feed. Whatever's easier for them to read, they can do.
Without knowing your application, I can't offer specific advice.
That said, it's common in these sorts of systems to have a level of severity. You could have a query string parameter that you tack on to the end of the URL that specifies the severity. If set to "DEBUG" you would see every event, no matter how trivial. If you set it to "FATAL" you'd only see the events that that were "System Failure" in magnitude.
If there are still too many events, you may want to sub-divide your events in to some sort of category system. Again, I would have this as a query string parameter.
You can then have multiple RSS feeds for the various categories and severities. This should allow you to tune the level of alerts you get an acceptable level.
In this case, it's more of a manager's dashboard: how much work was put into support today, is there anything pressing in the log right now, and for when we first arrive in the morning as a measure of what went wrong with batch jobs overnight.
Okay, I decided how I'm gonna handle this. I'm using the timestamp field for each column and grouping by day. It takes a little bit of SQL-fu to make it happen since of course there's a full timestamp there and I need to be semi-intelligent about how I pick the log message to show from within the group, but it's not too bad. Further, I'm building it to let you select which application to monitor, and then showing every message (max 50) from a specific day.
That gets me down to something reasonable.
I'm still hoping for a good answer to the more generic question: "How do you syndicate many important messages, where missing a message could be a problem?"