We're using cucumberJS on a fairly large codebase with hundreds of cucumber scenarios and we've been running into issues with steps reuse.
Since all the steps in Cucumber are global, it's quite difficult to write steps like "and I select the first item in the list" or similar that would be similarly high-level. We end up having to append "on homepage" (so: "I select the first item in the list of folders on homepage") which just feels wrong and reads wrong.
Also, I find it very hard to figure out what the dependencies between steps are. For example we use a "and I see " pattern for storing a page object reference on the world cucumber instance to be used in some later steps. I find that very awkward since those dependencies are all but invisible when reading the .feature files.
What's your tips on how to use cucumber within a large team? (Including "ditch cucumber and use instead" :) )
Write scenarios/steps that are about what you are doing and why you are doing it rather than about how you do things. Cucumber is a tool for doing BDD. The key word here is Behaviour, and its interpretation. The fundamental idea behind Cucumber and steps is that each piece of behaviour (the what) has a unique name and place in the application, and in the application context you can talk about that behaviour using that name without ambiguity.
So your examples should never be in steps because they are about HOW your do something. Good steps never talk about clicking or selecting. Instead they talk about the reason Why you are clicking or selecting.
When you follow this pattern you end up with fewer steps at a higher level of abstraction that are each focused on a particular topic.
This pattern is easy to implement, and moderately easy to maintain. The difficulty is that to write the scenarios you have to have a profound understanding of what you are doing and why its important so you can discover/uncover the language you need to express yourself distinctly, clearly and simply.
I'll give my standard example about login. I use this because we share an understanding of What login is and Why its important. Realise before you can login that you have to be registered and that is complex.
Scenario: Login
Given I am registered
When I login
Then I should be logged in
The implementation of this is interesting in that I delegate all work to helper methods
Given I am registered
#i = create_registered_user
end
When I login
login_as(user: #i)
end
Then I should be logged in
should_be_logged_in
end
Now your problem becomes one of managing helper methods. What you have is a global namespace with a large number of helper methods. This is now a code and naming problem and All you have to do is
keep the number of helper methods as small as possible
keep each helper method simple
ensure there is no ambiguity between method names
ensure there is no duplication
This is still a hard problem, but
- its not as hard as what you are dealing with
- getting to this point has a large number of additional benefits
- its now a code problem, lots of people have experience of managing code.
You can do all these things with
- naming discipline (all my methods above have login in their name)
- clever but controlled use of arguments
- frequent refactoring and code cleaning
The code of your helper methods will have
- the highest churn of all your application code
- the greatest need to be simple and clear
So currently your problem is not about Cucumber its about debt you have with your existing scenarios and their implementation. You have to pay of your debt if you want things to improve, good luck
It looks like all the Spark examples found in web are built in as single long function (usually in main)
But it is often the case that it makes sense to break the long call into functions like:
Improve readability
Share code between solution paths
A typical signature would look like this (this is Java code but similar signature would appear in all languages)
private static Dataset<Row> myFiltering(Dataset<Row> data) {
return data.filter(functions.col("firstName").isNotNull()).filter(functions.col("lastName").isNotNull());
}
The problem here is that there is no safety for the content of the Row, as there is no enforcement on the fields, and calling the function becomes not only a matter of matching the singnature but also the content of Row. Which obviously may (and does in my case) cause errors.
What is the best practice you enforce in large scale development environments? do you leave the code as one long function? do you suffer every time you change field names?
Yes, you should split your method into smaller methods. Be aware, that many small functions also are not much readable ;)
My rules:
Split some chain of transformation if we can name it - if we have name, it means that this is some kind of subfunction
If there are many functions of the same domain - extract new class or even package.
KISS: don't split if your function call chain is short and also describes some subfunction, even if some lines may be extracted - it is not as much readable to read many many custom functions
Any larger - not in 1-3 lines - filters, maps I suggest to extract to method and use method reference
Marked as Community Wiki, because this is only my point of view and it's OT for StackOverflow. It someone else has any other suggestions, please share it :)
I'm not a native English speaker and I'm wondering how's better to naming a variable with multiple words.
For example, I have two urls. One is for querying and the other is for submitting.
Should them be named as url_query, url_submit? Or querying_url, submitting_url? Or query_url, submit_url? Or things like submission_url?
I prefer url_query and url_submit. They are neat if I have a lot different urls for different purposes. But it sounds strange if I say it out.
This is a highly opinionated subject and it may be best to consult a specific coding style of your choice.
However, in general you want you variable names to be easily understood and readable.
For this reason items such as url_submit and url_query may be better option, as both are fairly understandable.
There are many different naming conventions, but the most important factor here is readability and implementation. Remember that comments will also help the readability as well.
You can name them however they feel right to you. Typically I camelCase them however instead of using underscores.
submitUrls/queryUrls
Try to think globally however as you may have these replicated in other pages and you may be able to build off your existing names like *action/*Thing(ie submit + what to submit "submitUrls")
Also, If something doesn't seem to make a good deal of sense to you when you're naming it. It is wise to add a line of comments in to identify what this function does later down the road if you have a bunch of functions named of actions and items.(Things)
I really this is a hugely subjective topic but here is my current take:
When calling methods which do not form part of the .NET BCL named parameters should always be used as the method signatures may well change, especially during the development cycle of my own applications.
Although they might appear more verbose they are also far clearer.
Is the above a reasonable approach to calling methods or have I overlooked something fundamental?
I think it's over the top, personally. (I also believe it's more correct and clearer to call them named arguments - the parameters always have names, as that's part of the declaration.)
In many cases the meaning is crystal clear from the method name - particularly if there are only a couple of arguments. Why bother to add the name? Why does the fact that the name may change affect this?
I would suggest using named arguments:
When optional parameters are also being used
When there are multiple parameters of the same type, so they can be confused (e.g. a dialog box's title and content text)
When you're using null for an argument, and it's not clear what it's doing
To put it another way, how often did not having named arguments cause you confusion before C# 4? In my case it's certainly a non-zero number of times - the situations above do happen - but it's not something that regularly got in my way. Optional parameters make it more reasonable for a method (or particularly a constructor) to have potentially many parameters, and that leads to named arguments being more useful (and indeed necessary if you want to specify "late" optional parameters having skipped earlier ones).
I need to define a class that represents a real-life event -- like a "movie premier", "party", etc. I will be creating a set of database objects to store the data for each event and define relationships with other data we have (e.g. venue, people, etc.).
The word "event" has a different meaning in the context of software, so I'd like to name the class something other than "event".
Any ideas on another name?
This related post asks a similar question, but I think all of the suggestions lack creativity -- basically #event, the case-sensitive name Event or use the old-school naming convention CEvent. Technically good solutions, but they don't help when discussing the data objects with peers (my speech and listening abilities are case-insensitive) and don't convey any information on how the class is not an event in the traditional use of the term.
One option would be CalendarEvent, to make it obvious that this is a real-world event tied to a given date.
Activity come to mind.
How about Happening or Occasion?
Normally I'd recommend function, but it too has specific meanings in the context of software. ;)
Occasion might be a good synonym.
The thesaurus lists the following as synonyms of the word event:
accident, act, action, advent,
adventure, affair, appearance,
business, calamity, case, catastrophe,
celebration, ceremony, chance,
circumstance, coincidence,
conjuncture, crisis, deed,
development, emergency, episode,
experience, exploit, fact, function,
holiday, incident, juncture, marvel,
matter, milestone, miracle,
misfortune, mishap, mistake, occasion,
occurrence, pass, phase, phenomenon,
predicament, proceeding, shift,
situation, story, thing*, tide,
transaction, triumph, turn, wonder
Surely one of them would suffice... if not, you can prepend or wrap the word event to make it a non-keyword. Something like #event or [event] although, I have to say that I don't personally like this practice even though it is syntactically permissable.
You could call it a 'Rendezvous'. You could also just make up a word. If this is a key concept in your domain you could abbreviate one of the other suggested names. Things like:
CalenderEvent becomes Calvent
SocialEvent becomes Socent
RealWorldEvent becomes Revent
HumanActivity becomes HAct
Those quick examples might be terrible examples but they are short, don't collide with language or library names, and will become real meaningful words for you and your coworkers very quickly if you work with them frequently.
Perhaps "Affair" or "Advent" -- you could also check the thesaurus:
http://thesaurus.reference.com/browse/event
Entry or EventEntry are probably what I would go with.
I can appreciate you want to avoid confusion with events in the programming sense, but my take on it is that maybe you should go with the most obvious name; program to your domain, and things stay readable and easier to design and maintain.