When using examples in PyBehave can you enter them into a table within a step? - python-behave

One of my steps in my behave test generates a CSV file from a table within the step example below
Scenario: Some_name for attribute 1
Given I add a file with the following data for attribute_1
|Identifier|value_1|value_2|attribute_1|
|1234 |yes |no |no |
When I process the file
Then a thing happens
And attribute_1 is processed correctly
The system under test needs me to run several tests with different values for attribute in order to save me having to have multiple tests written out I would like to use the outline/examples approach.
Does behave allow me to enter a parameter for a table value? eg
Scenario Outline: Some_name for attributes
Given I add a file with the following data for attribute <attribute>
|Identifier|value_1|value_2|<attribute>|
|1234 |yes |no |no |
When I process the file
Then a thing happens
And attribute <attribute >is processed correctly
Examples:
|attribute |
|attribute_1|
|attribute_2|
If it does not is there an alternative way of doing this using behave I know there are hacky ways I could make this work but want to see if Behave will handle this without needing to code workarounds.

Related

In cucumber background steps are passed for first scenario outline but failing for the second scenario outline

Feature: search by customer
Background:
Given user selects search type as customer
Scenario Outline: search customer
When slects customer type as customer
Then enter the customer id as "<customer>" in search
And clicks on search icon to search
Examples:
|customer|
|248069 |
Scenario Outline: Search hierarchy
When slects customer type as hierarchy
Then enter the hierarchy id as "<hierarchy>" in search
And clicks on search icon to search
Examples:
|hierarchy |
|3779213 |
If the second scenario results in an error when executed, I would modify the first scenario outline so that it could run both scenarios. You will need to parameterize the step definition for the first scenario outline something like this:
Scenario Outline: search user types
When selects customer type as <type>
Then enter the customer id as <id> in search
And clicks on search icon to search
Examples:
| type | id |
| customer | 248069 |
| hierarchy | 3779213 |
You will need to modify the step definitions that work (the ones used by the first scenario outline). My suspicion is that the step definition for the first step in the second scenario (slects customer type as hierarchy) is broken and causing your issue. Even if it is not defective, there is no good reason to have two step definition that basically do the same thing. Pass a parameter and make a decision inside the method body to make a decision based on the parameter passed if you need to execute an alternate path.
If you make these changes and the second scenario example fails, you can assume that it is due to a bad parameter being passed. In this case, the id parameter is one character longer in the second scenario example. It is possible this could be the problem.
Since you haven't provided a specific description of the error you are getting, it is impossible to say for certain what solution will work for you. That said, this is my best guess.

Join in Laravel's Eloquent

I have a visit Model and I'm getting the data I want like that:
$app_visits = Visit::select([
'start',
'end',
'machine_name'
])->where('user_id', $chosen_id)->get();
But I want to add points for every visit. Every visit has an interaction (but there's no visit_id (because of other system I cannot add it).
Last developer left it like that:
$interactions = Interaction::where([
'machine_name' => $app_visit->machine_name,
])->whereBetween('date', [$app_visit->start, $app_visit->end])->get();
$points = 0;
foreach ($interactions as $interaction) {
$points += (int)$interaction->app_stage;
}
$app_visits[$key]['points'] = $points
But I really don't like it as it's slow and messy. I wanted to just add 'points' sum to the first query, to touch database only once.
#edit as someone asked for database structure:
visit:
|id | start | end | machine_name | user_id
inteaction:
|id | time | machine_name | points
You can use a few things in eloquent. Probably the most useful for this case, is the select(DB::raw(sql...)) as you will have to add a bit of raw sql to retrieve a count.
For example:
return $query
->join(...)
->where(...)
->select(DB::raw(
COUNT(DISTINCT res.id) AS count'
))
->groupBy(...);
Failing that, I'd just replace the eloquent with raw sql. We've had to do that a fair bit, as our data sets are massive, and eloquent model building has proven a little slow.
Update as you've added structure. Why not just add a relation to Interaction, based upon machine_name (or even a custom method using raw sql that calculates the points), and use: Visits::with('interaction.visitPoints')->...blah ?
Take a look at DB instead of Eloquent:
https://laravel.com/docs/5.6/queries
For more complex and efficient queries.
There is also a possibility to use raw SQL with this facade.

How to get the output of a powershell command into an array

I am trying to get the output of a powershell command into an array, but it seems not to work. In fact I want to address the output with a row and a column index.
e.g.
$a=Get-Service
With output (part)
Status Name DisplayName
------ ---- -----------
Stopped AeLookupSvc Application Experience
Stopped ALG Application Layer Gateway Service
Stopped AppIDSvc Application Identity
Running Appinfo Application Information
Stopped AppMgmt Application Management
I want to address for the second line the DisplayName, e.g.
$a[2][2]
And it should give then
Application Layer Gateway Service
But this does not seem to work.
Can anybody help?
This type of question makes me think that you're probably coming from a Unix background, and are accustomed to having to deal with indicies and column index, that sort of thing.
Fundamentally, PowerShell is an object-oriented scripting language. You simply don't need to do what you're asking about here.
For instance, if you want to capture the results, then grab a property for one of the objects, here's how that's done.
First, capture the output.
$a=Get-Service
Now, you want a particular property of a particular entity. To get that, index into the object you want.
>$a[2]
Status Name DisplayName
------ ---- -----------
Stopped AJRouter AllJoyn Router Service
To select the .DisplayName, all you have to do is append that to the end of your previous command.
> $a[2].DisplayName
AllJoyn Router Service
If you want to select multiple values, you could use this approach instead.
#Select multiple values from one entity
$a[2] | select DisplayName, Status
>DisplayName Status
----------- ------
Application Layer Gateway Service Stopped
#Select multiple values from each in the array
$a | select DisplayName, Status
>DisplayName Status
----------- ------
Adobe Acrobat Update Service Running
AllJoyn Router Service Stopped
Application Layer Gateway Service Stopped
Application Identity Stopped
This is not possible without a mapping from property names to array indices. Note that what you see in the output is just a partial list of properties (defined in an XML file somewhere). So there isn't even an easy way to convert those to array indices.
However, I also don't quite understand your need here. You can get the second service with $a[1], as expected. And then you can get its DisplayName property value with $a[1].DisplayName. PowerShell uses objects throughout. There is simply no need to fall back to text parsing or cryptic column indices just to get your data. There's an easier way.
The output from Get-Service that you see in the Console may look like an array (as it is formatted as a table when sent to the Console), but it is actually an 'System.ServiceProcess.ServiceController' object.
Rather than using row and column designations, you need to use the name of the property to retrieve it, so for your example:
$a[2].DisplayName will return Application Layer Gateway Service

Neo4j: How to merge existing data (in a database) and non existing data (in CSV)

I already have nodes as "projects" in my database. Also I have tags in a CSV.
The CSV looks like this:
|name|
|Information1|
|Information2|
|...|
I'd like to put them both together, so that one specific project will have all information in the CSV with the relationship "belongs_to".
The result should looks like this:
Information1 - belongs_to -> Project1
Information2 - belongs_to -> Project1
How can I do this? I tried different things, but nothing was right.
I thought I could load the CSV first and secondly get the relationship like:
USING PERIODIC COMMIT
LOAD CSV WITH HEADERS FROM "file:C:/.../projects.csv" AS row
CREATE (:AddInformation {name: row.name});
...
MATCH (p:PROJECT { id:1 })
WITH range(1,4) AS RANGE, p
FOREACH (r IN RANGE |
MERGE (add:AddInformation { id:r })-[rel:belongs_to]->(p))
This works, but in this case there were just new AddInformation, not the one I was looking for.
So again my question: How can I put one project together (with a relationship) with information from a specific CSV?
(Would it help to identify the AddInformation by ID in the CSV or add the information, that they should match with a specific project?)
Best regards, Finfan
FOREACH isn't the right one for that.
Now I used a second property for my AddInformation.
The CSV is now looking like this:
|name |property|
|Information1|... |
|Information2|... |
|... |... |
So firstly I load this CSV, secondly I use this command:
MATCH (p:Project), (add:AddInformation) WHERE id(p)=8 AND HAS (add.property)
MERGE (add)-[:belongs_to]->(p)
Afterwards I delete this property and everything is fine.
MATCH (m {property:"Insert"}) REMOVE m.property RETURN m

Best way to store user-submitted item names (and their synonyms)

Consider an e-commerce application with multiple stores. Each store owner can edit the item catalog of his store.
My current database schema is as follows:
item_names: id | name | description | picture | common(BOOL)
items: id | item_name_id | picture | price | description | picture
item_synonyms: id | item_name_id | name | error(BOOL)
Notes: error indicates a wrong spelling (eg. "Ericson"). description and picture of the item_names table are "globals" that can optionally be overridden by "local" description and picture fields of the items table (in case the store owner wants to supply a different picture for an item). common helps separate unique item names ("Jimmy Joe's Cheese Pizza" from "Cheese Pizza")
I think the bright side of this schema is:
Optimized searching & Handling Synonyms: I can query the item_names & item_synonyms tables using name LIKE %QUERY% and obtain the list of item_name_ids that need to be joined with the items table. (Examples of synonyms: "Sony Ericsson", "Sony Ericson", "X10", "X 10")
Autocompletion: Again, a simple query to the item_names table. I can avoid the usage of DISTINCT and it minimizes number of variations ("Sony Ericsson Xperia™ X10", "Sony Ericsson - Xperia X10", "Xperia X10, Sony Ericsson")
The down side would be:
Overhead: When inserting an item, I query item_names to see if this name already exists. If not, I create a new entry. When deleting an item, I count the number of entries with the same name. If this is the only item with that name, I delete the entry from the item_names table (just to keep things clean; accounts for possible erroneous submissions). And updating is the combination of both.
Weird Item Names: Store owners sometimes use sentences like "Harry Potter 1, 2 Books + CDs + Magic Hat". There's something off about having so much overhead to accommodate cases like this. This would perhaps be the prime reason I'm tempted to go for a schema like this:
items: id | name | picture | price | description | picture
(... with item_names and item_synonyms as utility tables that I could query)
Is there a better schema you would suggested?
Should item names be normalized for autocomplete? Is this probably what Facebook does for "School", "City" entries?
Is the first schema or the second better/optimal for search?
Thanks in advance!
References: (1) Is normalizing a person's name going too far?, (2) Avoiding DISTINCT
EDIT: In the event of 2 items being entered with similar names, an Admin who sees this simply clicks "Make Synonym" which will convert one of the names into the synonym of the other. I don't require a way to automatically detect if an entered name is the synonym of the other. I'm hoping the autocomplete will take care of 95% of such cases. As the table set increases in size, the need to "Make Synonym" will decrease. Hope that clears the confusion.
UPDATE: To those who would like to know what I went ahead with... I've gone with the second schema but removed the item_names and item_synonyms tables in hopes that Solr will provide me with the ability to perform all the remaining tasks I need:
items: id | name | picture | price | description | picture
Thanks everyone for the help!
The requirements you state in your comment ("Optimized searching", "Handling Synonyms" and "Autocomplete") are not things that are generally associated with an RDBMS. It sounds like what you're trying to solve is a searching problem, not a data storage and normalization problem. You might want to start looking at some search architectures like Solr
Excerpted from the solr feature list:
Faceted Searching based on unique field values, explicit queries, or date ranges
Spelling suggestions for user queries
More Like This suggestions for given document
Auto-suggest functionality
Performance Optimizations
If there were more attributes exposed for mapping, I would suggest using a fast search index system. No need to set aliases up as the records are added, the attributes simply get indexed and each search issued returns matches with a relevance score. Take the top X% as valid matches and display those.
Creating and storing aliases seems like a brute-force, labor intensive approach that probably won't be able to adjust to the needs of your users.
Just an idea.
One thing that comes to my mind is sorting the characters in the name and synonym throwing away all white space. This is similar to the solution of finding all anagrams for a word. The end result is ability to quickly find similar entries. As you pointed out, all synonyms should converge into one single term, or name. The search is performed against synonyms using again sorted input string.

Resources