How to add switch statement in feature file?
I need to verify around 20 web tables data with database. for this I'm writing one common scenario which will work for all the web tables based on the condition.
Is there any possible like below in karate framework - Scenario level
switch(expression){
case table1:
//code to be executed;
break;
case table2:
//code to be executed;
break; //optional
case table3:
//code to be executed;
break; //optional
......
default:
//code to be executed if all cases are not matched;
}
Karate is not designed for this. Maybe this part should be written in JS code or Java code which you can mix into a test.
That said, I'm pretty sure with some creativity you can use this approach: https://stackoverflow.com/a/59162760/143475
Also refer: https://stackoverflow.com/a/50350442/143475
Related
I'm using extbase in my extension and so I have *Repository classes where I can do simple queries just like:
public function getRecordsByCondition($config = [],$recordPages = null) {
$recordQuery = $this->createQuery();
$constraints = [];
if ($config['field1']) {
$constraints[] = $recordQuery->equals('field1',$config['field1']));
}
if ($config['field2']) {
$constraints[] = $recordQuery->equals('field2',$config['field2']));
}
if ($config['field3']) {
$constraints[] = $recordQuery->equals('field3',$config['field3']));
}
if (count($constraints)) {
if ($recordPages) {
$constraints[] = $recordQuery->in('pid',$recordPages);
$recordQuery->getQuerySettings()->setRespectStoragePage(false);
}
$recordQuery->matching($recordQuery->logicalAnd($constraints));
} else {
return false;
}
return $recordQuery->execute();
}
this will respect enableFields and other usual conditions.
on the other hand there is the option to do it in this way:
public function getrecords2($config,$recordPages) {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('tx_myext_domain_model_records');
$rawquery = $queryBuilder
->select('*')
->from('tx_myext_domain_model_records')
->where(
$queryBuilder->expr()->eq('field1',$config['field1']),
$queryBuilder->expr()->eq('field2',$config['field2']),
$queryBuilder->expr()->eq('field3',$config['field3']),
$queryBuilder->expr()->in('pid', $recordPages),
$queryBuilder->expr()->eq('deleted',0),
$queryBuilder->expr()->eq('hidden',0)
// starttime, endtime, language, workspace, ....
);
return $rawquery->execute()->fetchAll();
}
where I need to care about enablefields by myself but have more options to specify the query.
On the first view you can see that there are other methods (eq vs. equals) and these kind of doing queries have no relation. But both work on the same table.
Now I'm at a point where I need to change all my work from first to second variant as I need a query with a join to another table which can't be done with first variant (as far as I know).
Have I missed something or does the first variant needs some enhancements?
Well, I am not sure exactly the difference but let me try to express things in brief as per my knowledge :D
The main difference between both queries is Individual database queries (Typically I call it Extbase query, I'm not sure I am right or not!) and another is Doctrine DBAL Queries
1. Individual database queries
Here, as per the modern approach extension use Domain modeling. So, TYPO3 already enables a secure connection for model (Typically database table) and you can use relational table connection with Extbase function (Select, operational, join etc..) provided by TYPO3 core.
For more: https://docs.typo3.org/m/typo3/book-extbasefluid/master/en-us/6-Persistence/3-implement-individual-database-queries.html
2. Doctrine DBAL
Here, you enable connection manually for the database table using ConnectionPool class. Also, you have more feasibility to establish a relation (or Join you can say!) according to your need.
For more: https://docs.typo3.org/m/typo3/reference-coreapi/master/en-us/ApiOverview/Database/Index.html
However, you can use restriction for taking care if hidden delete etc.
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('tx_myext_domain_model_records');
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
$queryBuilder->getRestrictions()->add(GeneralUtility::makeInstance(HiddenRestriction::class));
$rawquery = $queryBuilder
->select('*')
->from('tx_myext_domain_model_records')
->where(
$queryBuilder->expr()->eq('field1',$config['field1']),
$queryBuilder->expr()->eq('field2',$config['field2']),
$queryBuilder->expr()->eq('field3',$config['field3']),
$queryBuilder->expr()->in('pid', $recordPages)
// starttime, endtime, language, workspace, ....
);
See: https://docs.typo3.org/m/typo3/reference-coreapi/master/en-us/ApiOverview/Database/RestrictionBuilder/Index.html
I know this is not a sufficient and 100% correct answer. Everyone can welcome to correct me :)
where I need to care about enablefields by myself
That's not true. By default there are Restrictions active and you can enable or disable every Restriction with a short command.
I use both approaches, but I use the first one only on Extbase extensions, the second one on every other extension. (Yes, there exist extensions without Extbase)
I have a scenario to mock a soap service containing multiple soap actions. The response for every soap action is different. Is there a way to define all these in the same mock feature file?
I am looking for something like below.
When Scenario pathmatches(url);
if either soap action is the operation name or request contains a specific xml tag;
return response 1;
else
return response 2;
Is there a way to define all these in the same mock feature file?
Yes. Why not.
The selling point of Karate is that you can express any complicated logic as JavaScript expressions. Please refer to this section on conditional logic for ideas: https://github.com/intuit/karate#conditional-logic
The link above is for the http-client, but you can use the same concepts for mocks. A simple approach I recommend is to duplicate multiple Scenario: sections, maybe the pathMatches() will be repeated, but it will be very readable.
Scenario: pathMatches('/foo') && paramValue('client') != null
# do something
Scenario: pathMatches('/foo') && requestHeaders['SOAPAction'][0] == 'myaction'
You can also create a helper function in the Background:
Background:
* def isAction = function(a){ var tmp = requestHeaders['SOAPAction']; return tmp ? tmp[0] == a : null }
Scenario: pathMatches('/foo') && isAction('myaction')
You can also use the headerContains() function.
Scenario: pathMatches('/foo') && headerContains('SOAPAction','myaction')
see: https://intuit.github.io/karate/karate-netty/#headercontains
I have two scenarios named "X" and "Y" ( many others)
Before testing scenario "Y", I need to run Scenario "X" and return the results from scenario "X" to scenario "Y". How should I do that ?
I have tried 2 options
1: I have created background scenario for X but I am not able to return result from that background scenario X to scenario Y.
2: I have also tried using before hook up annotation.
(PS: I know while testing all test-cases should be independent of each other)
Perhaps the simplest way is to place both steps in the same class then use class instance variables.
public class SomeSteps {
private List<String> betweenStepsList;
#When("^I initialize a list in one step$")
public void iInitializeAListInOneStep() {
betweenStepsList = new ArrayList<String>(Arrays.asList("Peter","Piper","picked","a","peck","of","pickled","peppers"));
}
#Then("^I can access that list in a following step$")
public void iCanAccessThatListInAFollowingStep() {
System.out.println("Elements are:" + betweenStepsList);
}
}
EDIT
You did say two scenarios. When I face this issue I always find a way to combine the scenarios into one.
You could write the intermediate results to a file in the first scenario and then read them in the second. I never bother to do this myself but there are lots of tutorials on how to read and write files. Here is one for Java. Ruby or Python (you didn't specify) examples for writing then reading a file are also easily available.
Parallel execution is fine as long as both scenarios are in the same feature file.
i'm creating a zend framework 2 application and i'm sort of trying to implement what is explained here:
http://ralphschindler.com/2009/08/13/dynamic-assertions-for-zend_acl-in-zf
The demonstration that the code works is really nice, but it doesn't really apply to how a framework (utilizing mvc) works. Or maybe i'm just on the wrong track...
i've created a RouteListener like this :
class RouteListener implements ListenerAggregateInterface
{
public function attach(EventManagerInterface $events)
{
$this->listeners[] = $result = $events->attach(
MvcEvent::EVENT_DISPATCH, array($this, "checkAcl"), 100
);
}
}
the method checkAcl then checks if you're allowed to do what you want to do.
The resource and action are determined like this:
$resource = $routeMatch->getParam("controller");
$action = $routeMatch->getParam("action");
And the role is determined by the identity stored in the session (which implements Zend\Permissions\Acl\Role\RoleInterface)
Following the example: how do i determine if a user is allowed to edit a certain blog-post?
By the time acl is doing it's checking, the controller hasn't loaded the blogpost yet, so i'm not sure how to approach this. Unless i duplicate the retrieval of the blogpost in the assertion, but that i'm hoping there is a better way.
I'm also using doctrine for my persistence layer and in the end i've solved this problem using doctrine's Lifecycle Events. This allows you to trigger the acl-check whenever you want: when a entity (p.e. a blog-post) is loaded, or saved, etc.
I'm building a new app that is using NHibernate to generate the database schema but i can see a possible problem in the future.
Obviously you use all the data from your database is cleared when you update the schema but what stratagies do people use to restore any data to the new database. I am aware that massive changes to the schema will make this hard but was wondering how other people have dealt with this problem.
Cheers
Colin G
PS I will not be doing this against the live database only using it to restore test data for integration test and continuous integration
When testing, we use NHibernate to create the database, then a series of builders to create the data for each test fixture. We also use Sqlite for these tests, so they are lightening fast.
Our builders look a something like this:
public class CustomerBuilder : Builder<Customer>
{
string firstName;
string lastName;
Guid id = Guid.Empty;
public override Customer Build()
{
return new Customer() { Id = id, FirstName = firstName, LastName = }
}
public CustomerBuilder WithId(Guid newId)
{
id= newId;
return this;
}
public CustomerBuilder WithFirstName(string newFirstName)
{
firstName = newFirstName;
return this;
}
public CustomerBuilder WithLastName(string newLastName)
{
lastName = newLastName;
return this;
}
}
and usage:
var customer = new CustomerBuilder().WithFirstName("John").WithLastName("Doe").Build();
Because every line of code is written with TDD, we build up a comprehensive suite of data from scatch and will generally refactor some of it to factories that will wrap the above and make it a breeze to get dummy data in.
I think it is a good thing in many situations to let NHibernate generate the schema for you. To recreate the test data you either use code driven by a testing framework (such as NUnit) or you could export your test data as a SQL script which you can run after you have updated the schema.
Just a quick question directed #Chris Canal-
I understand that using a fluent interface to build your objects makes it look readable, but is it really worth the extra effort required to write these "builders" when you can use C# 3.0 syntax?
i.e. take your example:
var customer = new CustomerBuilder().WithFirstName("John").WithLastName("Doe").Build();
is this really worth the effort in constructing a "builder" when instead you can do this (which is arguably just as readable, and in fact less code)?:
var customer = new Customer { FirstName = "John", LastName = "Doe" };
We don't update the schema from NHibernate. We use SQLCompare to move database schemas across environments. SQLCompare does this non-destructively.
If you're already using NHibernate I would recommend creating the test data with code.
We do it similarly at our company. We use NHibernate to generate the database for our development and testing purposes. For testing we use SQLite as the back-end and just simply generate the test data separately for each test test suite.
When updating our staging/production servers we use SQLCompare and some manual editing if changes are more complex.