How to create, delete and update Test Steps listed in VSTS Test Cases - rest

We are working on building an approach that automatically update test suite's execution metrics onto the VSTS server. After going through the REST API document for VSTS, we were able to do the following using those automated APIs
Create a Test RUN with desired list of existing test cases
Update the Test RESULTS (outcome and status) for the above created Test RUN
Now it is possible to update whether the Test Case is Pass, Fail or any other available outcomes. But we are looking for an automated approach with which we can update the status of each Test Step inside each Test Case to Pass, Fail or any other available outcomes.
Hope I have explained our pain area in more understandable way.
Please reply your suggestions.
Thanks in advance.

Test Steps listed in VSTS Test Cases still belongs to test result.
If you get a test result with parameter `detailsToInclude=Iterations', you will see there is "actionResults" to determine test steps outcome:
Get https://xxx.visualstudio.com/TestCase/_apis/test/runs/xx/results/xx?api-version=3.0-preview&detailsToInclude=Iterations
But I've tried update "actionResults" with REST api Update test results for a test run, and found it doesn't support update "actionResults". Your requirement can not be achieved with rest api.
Instead of REST api, you can use the client api as this case mentioned: How to add/update individual result to each test step in testcase of VSTS/TFS programatically
Simple sample:
int testpointid = 176;
var u = new Uri("https://[account].visualstudio.com");
VssCredentials c = new VssCredentials(new Microsoft.VisualStudio.Services.Common.VssBasicCredential(string.Empty, "[pat]"));
TfsTeamProjectCollection _tfs = new TfsTeamProjectCollection(u, c);
ITestManagementService test_service = (ITestManagementService)_tfs.GetService(typeof(ITestManagementService));
ITestManagementTeamProject _testproject = test_service.GetTeamProject("scrum2015");
ITestPlan _plan = _testproject.TestPlans.Find(115);
ITestRun testRun = _plan.CreateTestRun(false);
testRun.Title = "apiTest";
ITestPoint point = _plan.FindTestPoint(testpointid);
testRun.AddTestPoint(point, test_service.AuthorizedIdentity);
testRun.Save();
testRun.Refresh();
ITestCaseResultCollection results = testRun.QueryResults();
ITestIterationResult iterationResult;
foreach (ITestCaseResult result in results)
{
iterationResult = result.CreateIteration(1);
foreach (Microsoft.TeamFoundation.TestManagement.Client.ITestStep testStep in result.GetTestCase().Actions)
{
ITestStepResult stepResult = iterationResult.CreateStepResult(testStep.Id);
stepResult.Outcome = Microsoft.TeamFoundation.TestManagement.Client.TestOutcome.Passed; //you can assign different states here
iterationResult.Actions.Add(stepResult);
}
iterationResult.Outcome = Microsoft.TeamFoundation.TestManagement.Client.TestOutcome.Passed;
result.Iterations.Add(iterationResult);
result.Outcome = Microsoft.TeamFoundation.TestManagement.Client.TestOutcome.Passed;
result.State = TestResultState.Completed;
result.Save(true);
}
testRun.State = Microsoft.TeamFoundation.TestManagement.Client.TestRunState.Completed;
results.Save(true);

Related

Spring Batch repeat step until a criteria is met

I have this Spring Batch flow:
return jobBuilderFactory.get(JOB).preventRestart().incrementer(new RunIdIncrementer()).listener(jobCompletionListener)
.start(clean).next(generateFiles1).next(callApi1)
.next(clean).next(generateFiles2).next(callApi2)
.next(clean).next(generateFiles3).next(callApi3)
.next(clean).next(generateFiles4).next(callApi4)
.build();
I must repeat the first three steps (clean, generateFiles1 and callApi1) until a certain criteria is met (I have to count some data in the database to check if I need to call the API again). And so on for the next three steps.
I have seen the on and to functions explained there, but it seems to me that it does not allow to write such loops.
I could define such flows:
final FlowBuilder<Flow> flowBuilderStep1 = new FlowBuilder<>("Step1");
flowBuilderStep1.start(clean).next(generateFiles1).next(callApi1).end();
final Flow step1 = flowBuilderStep1.build();
final FlowBuilder<Flow> flowBuilderStep2 = new FlowBuilder<>("Step2");
flowBuilderStep2.start(clean).next(generateFiles2).next(callApi2).end();
final Flow step2 = flowBuilderStep2.build();
And then build the conditional structure (maybe after adding Decider or afterStep() some place):
return jobBuilderFactory.get(JOB).preventRestart().incrementer(new RunIdIncrementer()).listener(jobCompletionListener)
.start(step1).on("RETRY").to(step1).on("CONTINUE")
.to(step2).on("RETRY").to(step2).on("CONTINUE")
.to(step3).on("RETRY").to(step3).on("CONTINUE")
.to(step4)
.end().build();
But I don't think it would loop properly. Am I right? Can a loop be accomplished (without a xml config)?
I had to do something like that to make it work.
return jobBuilderFactory.get(JOB).preventRestart().incrementer(new RunIdIncrementer()).listener(jobCompletionListener)
.start(step1).next(step1Decider).on(RETRY).to(step1).from(step1Decider).on(CONTINUE)
.to(step2).next(step2Decider).on(RETRY).to(step2).from(step2Decider).on(CONTINUE)
...

Aha!<>VSTS Integration - Aha! adjusted Stack Rank in VSTS - tips on reverting?

While integrating with VSTS, I accidentally wiped out the stack rank in VSTS for my 100+ features. My first choice would be to undo the import. Does anyone know how I could revert the action on either the Aha or VSTS side? My second choice would be to edit one by one. I can go into the details of each story and see the original stack rank, but I can't seem to be able to find where I could then reenter it one by one.
If there isn't any other action performed on these work items after that, the quick way is getting the Stack Rank value in the previous revision of the work items and updating the work items with the returned stack rand via coding. Following is the code sample to update the value of Stack Rank to previous version for a single work item:
using Microsoft.TeamFoundation.Client;
using System;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
namespace ConsoleX
{
class Program
{
static void Main(string[] args)
{
Uri url = new Uri("https://vstsaccount.visualstudio.com");
TfsTeamProjectCollection ttpc = new TfsTeamProjectCollection(url);
WorkItemStore wis = ttpc.GetService<WorkItemStore>();
int workitemid = 12;
WorkItem wi = wis.GetWorkItem(workitemid);
int previousrevision = wi.Revision - 2;
string previousstackrank = wi.Revisions[previousrevision].Fields["Stack Rank"].Value.ToString();
wi.Fields["Stack Rank"].Value = previousstackrank;
wi.Save();
}
}
}
For you scenario, just add some code to query that 100+ features and update them one by one.

Using the output of a [ValueSourceAttribute] Nunit Test in the following Test

I am developing a unit test project where I create an item in a test, then create sub items for it in the following test.
These tests are parameterized tests, and these parameters are collected in the runtime, so when the project starts it starts. It fails to retrieve the parent item from the database because they are not created yet "as I haven't run the first test yet".
Is there a workaround for this?
The first function:
[Test, Sequential]
public void AddInitiative([ValueSourceAttribute("Get_AddInitiatives_Data_FromExcel")]AddInitiative Initiative_Object)
{
string URL = "http://" + Server_name + Port_number + "/IntegrationHub/IntegrationHub.svc/RestUnsecure/AddInitiative";
string Token = Get_Security_token("gpmdev\\administrator", "Xyz7890", TenantID_Input);
var Response = POST_Request(Initiative_Object, URL, Token);
Guid Returned_GUID = GenericSerializer<Guid>.DeserializeFromJSON(Response);
DataBase_Queries DB = new DataBase_Queries();
List<StrategyItem> StrategyItemsFromDB=DB.GetStrategyItemByID(Returned_GUID.ToString());
Assert.AreEqual(Initiative_Object.Initiative.Name_En, StrategyItemsFromDB[0].Name_En);
}
The second function that fails:
[Test, Sequential]
public void AddInitiativeMilestones([ValueSourceAttribute("Get_AddInitiativeMilestones_Data_FromExcel")]AddMilestone Milestone_Object)
{
string URL = "http://" + Server_name + Port_number + "/IntegrationHub/IntegrationHub.svc/RestUnsecure/AddInitiativeMilestones";
string Token = Get_Security_token("gpmdev\\administrator", "Xyz7890", TenantID_Input);
var Response = POST_Request(Milestone_Object, URL, Token);
List<Milestone> Returned_Milestone = GenericSerializer<List<Milestone>>.DeserializeFromJSON(Response);
DataBase_Queries DB = new DataBase_Queries();
List<StrategyItem> StrategyItemsFromDB = DB.GetStrategyItemByID(Returned_Milestone[0].ID.ToString());
Assert.AreEqual(Milestone_Object.Milestones[0].Name_En, Returned_Milestone[0].Name_En);
Assert.AreEqual(Milestone_Object.Milestones[0].Name_En,StrategyItemsFromDB[0].Name_En);
}
Update: When I clicked from the GUI on Clear fixture the test data was reloaded, but it there a way to do that without the GUI?
It's generally bad practice in unit tests to have one test depend on (i.e. use output from) another test. In this case, with NUnit, it's actually impossible.
It's impossible because NUnit creates tests long before they are executed. NUnit will call your TestCaseSource methods at what we call "load time" when NUnit decides what tests exists and populates a GUI if you use one.
The code in your tests executes at "run time" for the tests. In a gui, this may happen multiple times for each load - every time you click Run, for example.
Note that I'm explaining this in terms of a GUI because it's an easy way to conceptualize it. NUnit works the same way whether you are running in batch or interactively.
If you want something to happen only once, before any tests are run, you can use OneTimeSetUp (TestFixtureSetUp in NUnit V2) to set it up. You can use a member of the class to save whatever you need from that execution and access it from your tests. However, this will still happen at "run time", decades (in computer terms) after your tests have been loaded.

Any way to ensure frisby.js test API calls go in sequential order?

I'm trying a simple sequence of tests on an API:
Create a user resource with a POST
Request the user resource with a GET
Delete the user resource with a DELETE
I've a single frisby test spec file mytest_spec.js. I've broken the test into 3 discrete steps, each with their own toss() like:
f1 = frisby.create("Create");
f1.post(post_url, {user_id: 1});
f1.expectStatus(201);
f1.toss();
// stuff...
f2 = frisby.create("Get");
f2.get(get_url);
f2.expectStatus(200);
f2.toss();
//Stuff...
f3 = frisby.create("delete");
f3.get(delete_url);
f3.expectStatus(200);
f3.toss();
Pretty basic stuff, right. However, there is no guarantee they'll execute in order as far as I can tell as they're asynchronous, so I might get a 404 on test 2 or 3 if the user doesn't exist by the time they run.
Does anyone know the correct way to create sequential tests in Frisby?
As you correctly pointed out, Frisby.js is asynchronous. There are several approaches to force it to run more synchronously. The easiest but not the cleanest one is to use .after(() -> ... you can find more about after() in Fisby.js docs.

How do I read environment variables in Postman tests?

I'm using the packaged app version of Postman to write tests against my Rest API. I'm trying to manage state between consecutive tests. To faciliate this, the Postman object exposed to the Javascript test runtime has methods for setting variables, but none for reading.
postman.setEnvironmentVariable("key", value );
Now, I can read this value in the next call via the {{key}} structure that sucks values in from the current environment. BUT, this doesn't work in the tests; it only works in the request building stuff.
So, is there away to read this stuff from the tests?
According to the docs here you can use
environment["foo"] OR environment.foo
globals["bar"] OR globals.bar
to access them.
ie;
postman.setEnvironmentVariable("foo", "bar");
tests["environment var foo = bar"] = environment.foo === "bar";
postman.setGlobalVariable("foobar", "1");
tests["global var foobar = true"] = globals.foobar == true;
postman.setGlobalVariable("bar", "0");
tests["global var bar = false"] = globals.bar == false;
Postman updated their sandbox and added a pm.* API. Although the older syntax for reading variables in the test scripts still works, according to the docs:
Once a variable has been set, use the pm.variables.get() method or,
alternatively, use the pm.environment.get() or pm.globals.get()
method depending on the appropriate scope to fetch the variable. The
method requires the variable name as a parameter to retrieve the
stored value in a script.