Coded webtest datasource problem
Hey all,
I've generated a coded webtest from a webtest that works just fine. When trying to run the unmodified newly generated coded test, I'm getting this error:
Error WebTest1Coded WebTests Could not run web test 'WebTest1Coded' on agent 'MachineName': Object reference not set to an instance of an object.
I've found that the culprit has something to do with this attribute:
[
DataSource("TestData1","Provider=SQLOLEDB;Data Source=ServerName;Integrated Security=SSPI;Initial Catalog=DatabaseName", Microsoft.VisualStudio.TestTools.WebTesting.DataBindingAccessMethod.Sequential,"TableName")]If I commit out this line, the test runs fine...but I can't access my test data.
Any ideas?
In your declaritive web test, do you data bind any request to a table column in the database?
If not, when you generate the coded web test and run it, you will get "Object reference not set to an instance of an object" error. This is a known bug. The workarounds for this are 1) delete the data source and generate the coded test (as you did), 2) data bind any request to a table column in the database and then generate the coded test.
If yes, then we need to find out why this does not work.
Thanks.
I'm not sure what you mean by declarative web test but I'm assuming this is the non-coded XML based test...is this assumption correct? In this test, I am making a call to a web service. In the string body, I'm binding to the datasource like this:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetArtistsByInitial xmlns=http://foo.com>
{{SessionID}}
<Initial>{{TestData1.a-z.initial}}</Initial>
<PageSize>10</PageSize>
<PageNumber>1</PageNumber>
</GetArtistsByInitial>
</soap:Body>
</soap:Envelope>
Again, this non-coded webtest works just fine. It's when I try to run the generated coded test that I get this error.
1. A web test is also called a declarative web test.
2. I tested on a similar scenario and could not repro your problem. Could you regenerate the coded test, run it and verify something for me in your code web test?
a. In the attribute section
Besides [DataSource("TestData1", "Provider=SQLOLEDB;Data Source=ServerName;Integrated Security=SSPI;Initial Catalog=DatabaseName", Microsoft.VisualStudio.TestTools.WebTesting.DataBindingAccessMethod.Sequential, "TableName")]
Do you see any line similar to
[DataBinding("TestData1", "TableName", "TableColumnName", "********")]?
b. In the GetRequestEnumerator(), look for the body string of your web service request
Do you see any line contain this.Context["********"]?
Thanks.
a. Nopes. There is no [DataBinding("TestData1", "TableName", "TableColumnName", "********")] attrib. Should there be?
b. Yeps. The context lines are found in the GetRequestEnumerator()
Could you paste your coded test?
Here you go.
//
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.42
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//
namespace WebTests
{
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualStudio.TestTools.WebTesting;
using Microsoft.VisualStudio.TestTools.WebTesting.Rules;
using CustomValidationRules;
[DataSource("TestData1", "Provider=SQLOLEDB;Data Source=Teamfoundation;Integrated Security=SSPI;Initial Cat" +
"alog=TestData", Microsoft.VisualStudio.TestTools.WebTesting.DataBindingAccessMethod.Sequential, "a-z")]
public class webservicesCoded : WebTest
{
public webservicesCoded()
{
this.PreAuthenticate = true;
this.Context.Add("WebServer1", "http://integration");
}
public override IEnumerator<WebTestRequest> GetRequestEnumerator()
{
this.BeginTransaction("Login");
WebTestRequest request1 = new WebTestRequest((this.Context["WebServer1"].ToString() + "/mgnv2/version1/AccountServices.asmx"));
request1.Method = "POST";
request1.Headers.Add(new WebTestRequestHeader("SOAPAction","http://foo.com/Login"));
StringHttpBody request1Body = new StringHttpBody();
request1Body.ContentType = "text/xml";
request1Body.BodyString = @"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body>
<Login xmlns=""http://foo.com"">
<UserName>foo</UserName>
<Password>foo</Password>
<SoftwareClientID>foo</SoftwareClientID>
<SoftwareVersion>1.1</SoftwareVersion>
</Login>
</soap:Body>
</soap:Envelope>";
request1.Body = request1Body;
if ((this.Context.ValidationLevel >= Microsoft.VisualStudio.TestTools.WebTesting.ValidationLevel.Low))
{
ValidationRuleFindText rule1 = new ValidationRuleFindText();
rule1.FindText = "LoginSuccessful";
rule1.IgnoreCase = false;
rule1.UseRegularExpression = false;
rule1.PassIfTextFound = true;
request1.ValidateResponse += new EventHandler<ValidationEventArgs>(rule1.Validate);
}
ExtractRegularExpression rule2 = new ExtractRegularExpression();
rule2.RegularExpression = "<SessionID>(.*)</SessionID>";
rule2.IgnoreCase = false;
rule2.Required = true;
rule2.Index = 0;
rule2.ContextParameterName = "SessionID";
request1.ExtractValues += new EventHandler<ExtractionEventArgs>(rule2.Extract);
yield return request1;
this.EndTransaction("Login");
this.BeginTransaction("BrowseByInitial");
WebTestRequest request2 = new WebTestRequest((this.Context["WebServer1"].ToString() + "/mgnv2/version1/CatalogServices.asmx"));
request2.Method = "POST";
request2.Headers.Add(new WebTestRequestHeader("SOAPAction", "http://musicgiants.com/MGNV2/Version1/GetArtistsByInitial"));
StringHttpBody request2Body = new StringHttpBody();
request2Body.ContentType = "text/xml";
request2Body.BodyString = (@"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body>
<GetArtistsByInitial xmlns=""http://musicgiants.com/MGNV2/Version1"">
"
+ (this.Context["SessionID"].ToString()
+ ("\r\n <Initial>"
+ (this.Context["TestData1.a-z.initial"].ToString() + "</Initial>\r\n <PageSize>10</PageSize>\r\n <PageNumber>1</PageNumber>\r\n " +
"</GetArtistsByInitial>\r\n </soap:Body>\r\n</soap:Envelope>"))));
request2.Body = request2Body;
if ((this.Context.ValidationLevel >= Microsoft.VisualStudio.TestTools.WebTesting.ValidationLevel.Low))
{
ValidateXMLTag rule3 = new ValidateXMLTag();
rule3.RequiredTagName = "MGArtist";
rule3.MinOccurrences = 100;
request2.ValidateResponse += new EventHandler<ValidationEventArgs>(rule3.Validate);
}
yield return request2;
this.EndTransaction("BrowseByInitial");
}
}
}
Could you paste your declarative web test here? You can right click on the test (from the solution explorer) , open it with XML editor, and copy the code.
Thanks.
Here you are...
<?xml version="1.0" encoding="utf-8"?>
<TestCase Name="webservices" Id="dc690469-3f1c-4ca6-943c-bfb4f513ed86" Owner="" Priority="0" Enabled="True" CssProjectStructure="" CssIteration="" Timeout="0" WorkItemIds="" Description="" CredentialUserName="" CredentialPassword="" PreAuthenticate="True" Proxy="" RequestCallbackClass="" TestCaseCallbackClass="">
<Items>
<TransactionTimer Name="Login">
<Items>
<Request Method="POST" Version="1.1" Url="{{WebServer1}}/AccountServices.asmx" ThinkTime="0" Timeout="0" ParseDependentRequests="True" FollowRedirects="True" RecordResult="True" Cache="False" ResponseTimeGoal="0" Encoding="utf-8">
<Headers>
<Header Name="SOAPAction" Value="http://foo.com/Login" />
</Headers>
<ValidationRules>
<ValidationRule Classname="Microsoft.VisualStudio.TestTools.WebTesting.Rules.ValidationRuleFindText, Microsoft.VisualStudio.QualityTools.WebTestFramework, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" Level="Low">
<RuleParameters>
<RuleParameter Name="FindText" Value="LoginSuccessful" />
<RuleParameter Name="IgnoreCase" Value="False" />
<RuleParameter Name="UseRegularExpression" Value="False" />
<RuleParameter Name="PassIfTextFound" Value="True" />
</RuleParameters>
</ValidationRule>
</ValidationRules>
<ExtractionRules>
<ExtractionRule Classname="Microsoft.VisualStudio.TestTools.WebTesting.Rules.ExtractRegularExpression, Microsoft.VisualStudio.QualityTools.WebTestFramework, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" VariableName="SessionID">
<RuleParameters>
<RuleParameter Name="RegularExpression" Value="<SessionID>(.*)</SessionID>" />
<RuleParameter Name="IgnoreCase" Value="False" />
<RuleParameter Name="Required" Value="True" />
<RuleParameter Name="Index" Value="0" />
</RuleParameters>
</ExtractionRule>
</ExtractionRules>
<StringHttpBody ContentType="text/xml">PAA/AHgAbQBsACAAdgBlAHIAcwBpAG8AbgA9ACIAMQAuADAAIgAgAGUAbgBjAG8AZABpAG4AZwA9ACIAdQB0AGYALQA4ACIAPwA+AA0ACgA8AHMAbwBhAHAAOgBFAG4AdgBlAGwAbwBwAGUAIAB4AG0AbABuAHMAOgB4AHMAaQA9ACIAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHcAMwAuAG8AcgBnAC8AMgAwADAAMQAvAFgATQBMAFMAYwBoAGUAbQBhAC0AaQBuAHMAdABhAG4AYwBlACIAIAB4AG0AbABuAHMAOgB4AHMAZAA9ACIAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHcAMwAuAG8AcgBnAC8AMgAwADAAMQAvAFgATQBMAFMAYwBoAGUAbQBhACIAIAB4AG0AbABuAHMAOgBzAG8AYQBwAD0AIgBoAHQAdABwADoALwAvAHMAYwBoAGUAbQBhAHMALgB4AG0AbABzAG8AYQBwAC4AbwByAGcALwBzAG8AYQBwAC8AZQBuAHYAZQBsAG8AcABlAC8AIgA+AA0ACgAgACAAPABzAG8AYQBwADoAQgBvAGQAeQA+AA0ACgAgACAAIAAgADwATABvAGcAaQBuACAAeABtAGwAbgBzAD0AIgBoAHQAdABwADoALwAvAG0AdQBzAGkAYwBnAGkAYQBuAHQAcwAuAGMAbwBtAC8ATQBHAE4AVgAyAC8AVgBlAHIAcwBpAG8AbgAxACIAPgANAAoAIAAgACAAIAAgACAAPABVAHMAZQByAE4AYQBtAGUAPgBkAGEAcgBpAG4APAAvAFUAcwBlAHIATgBhAG0AZQA+AA0ACgAgACAAIAAgACAAIAA8AFAAYQBzAHMAdwBvAHIAZAA+AHAAYQBzAHMAdwBvAHIAZAA8AC8AUABhAHMAcwB3AG8AcgBkAD4ADQAKACAAIAAgACAAIAAgADwAUwBvAGYAdAB3AGEAcgBlAEMAbABpAGUAbgB0AEkARAA+AGQAYQBkADcAZAA2AGMAOQAtADMAMwBjADcALQA0ADgANABkAC0AYgBmAGQAOAAtADcAZABlAGEAZABlADEAZgAzADEAMgAyADwALwBTAG8AZgB0AHcAYQByAGUAQwBsAGkAZQBuAHQASQBEAD4ADQAKACAAIAAgACAAIAAgADwAUwBvAGYAdAB3AGEAcgBlAFYAZQByAHMAaQBvAG4APgAxAC4AMQA8AC8AUwBvAGYAdAB3AGEAcgBlAFYAZQByAHMAaQBvAG4APgANAAoAIAAgACAAIAA8AC8ATABvAGcAaQBuAD4ADQAKACAAIAA8AC8AcwBvAGEAcAA6AEIAbwBkAHkAPgANAAoAPAAvAHMAbwBhAHAAOgBFAG4AdgBlAGwAbwBwAGUAPgA=</StringHttpBody>
</Request>
</Items>
</TransactionTimer>
<TransactionTimer Name="BrowseByInitial">
<Items>
<Request Method="POST" Version="1.1" Url="{{WebServer1}}/mgnv2/version1/CatalogServices.asmx" ThinkTime="0" Timeout="0" ParseDependentRequests="True" FollowRedirects="True" RecordResult="True" Cache="False" ResponseTimeGoal="0" Encoding="utf-8">
<Headers>
<Header Name="SOAPAction" Value="http://foo.com/GetArtistsByInitial" />
</Headers>
<ValidationRules>
<ValidationRule Classname="CustomValidationRules.ValidateXMLTag, CustomValidationRules, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Level="Low">
<RuleParameters>
<RuleParameter Name="RequiredTagName" Value="MGArtist" />
<RuleParameter Name="MinOccurrences" Value="100" />
</RuleParameters>
</ValidationRule>
</ValidationRules>
<StringHttpBody ContentType="text/xml">PAA/AHgAbQBsACAAdgBlAHIAcwBpAG8AbgA9ACIAMQAuADAAIgAgAGUAbgBjAG8AZABpAG4AZwA9ACIAdQB0AGYALQA4ACIAPwA+AA0ACgA8AHMAbwBhAHAAOgBFAG4AdgBlAGwAbwBwAGUAIAB4AG0AbABuAHMAOgB4AHMAaQA9ACIAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHcAMwAuAG8AcgBnAC8AMgAwADAAMQAvAFgATQBMAFMAYwBoAGUAbQBhAC0AaQBuAHMAdABhAG4AYwBlACIAIAB4AG0AbABuAHMAOgB4AHMAZAA9ACIAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHcAMwAuAG8AcgBnAC8AMgAwADAAMQAvAFgATQBMAFMAYwBoAGUAbQBhACIAIAB4AG0AbABuAHMAOgBzAG8AYQBwAD0AIgBoAHQAdABwADoALwAvAHMAYwBoAGUAbQBhAHMALgB4AG0AbABzAG8AYQBwAC4AbwByAGcALwBzAG8AYQBwAC8AZQBuAHYAZQBsAG8AcABlAC8AIgA+AA0ACgAgACAAPABzAG8AYQBwADoAQgBvAGQAeQA+AA0ACgAgACAAIAAgADwARwBlAHQAQQByAHQAaQBzAHQAcwBCAHkASQBuAGkAdABpAGEAbAAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBtAHUAcwBpAGMAZwBpAGEAbgB0AHMALgBjAG8AbQAvAE0ARwBOAFYAMgAvAFYAZQByAHMAaQBvAG4AMQAiAD4ADQAKACAAIAAgACAAIAAgAHsAewBTAGUAcwBzAGkAbwBuAEkARAB9AH0ADQAKACAAIAAgACAAIAAgADwASQBuAGkAdABpAGEAbAA+AHsAewBUAGUAcwB0AEQAYQB0AGEAMQAuAGEALQB6AC4AaQBuAGkAdABpAGEAbAB9AH0APAAvAEkAbgBpAHQAaQBhAGwAPgANAAoAIAAgACAAIAAgACAAPABQAGEAZwBlAFMAaQB6AGUAPgAxADAAPAAvAFAAYQBnAGUAUwBpAHoAZQA+AA0ACgAgACAAIAAgACAAIAA8AFAAYQBnAGUATgB1AG0AYgBlAHIAPgAxADwALwBQAGEAZwBlAE4AdQBtAGIAZQByAD4ADQAKACAAIAAgACAAPAAvAEcAZQB0AEEAcgB0AGkAcwB0AHMAQgB5AEkAbgBpAHQAaQBhAGwAPgANAAoAIAAgADwALwBzAG8AYQBwADoAQgBvAGQAeQA+AA0ACgA8AC8AcwBvAGEAcAA6AEUAbgB2AGUAbABvAHAAZQA+AA==</StringHttpBody>
</Request>
</Items>
</TransactionTimer>
</Items>
<DataSources>
<DataSource Name="TestData1" ConnectionDisplayValue="Provider=SQLOLEDB;Data Source=Foo;Integrated Security=SSPI;Initial Catalog=TestData" Connection="jZiZzUNGJ3XA2GC/s/ymqYcn4CtmIacpYJb3ZJw38EGdSgvNjEqTJsZSg/X/HNH6NibC39FbHbpeZ/8ALcDgkgRU9+hdVipqfvhVZm1klm5KiqT5TaZ6Qa8tZFU3p37S">
<Tables>
<DataSourceTable Name="a-z" AccessMethod="Sequential" />
</Tables>
</DataSource>
</DataSources>
<ContextParameters>
<ContextParameter Name="WebServer1" Value="http://integration" />
</ContextParameters>
</TestCase>
In your data source TestData1, could you check if table "a-z" contains column "initial"?
1. Open the web test in the Web Test Editor
2. Select SOAPAction header from any request.
3. In the property window, select Value field, and press F4.
4. Expand the data source (TestData1), what columns are listed there for table a-z?
Also, in your coded test, add the following line
[DataBinding("TestData1", "a-z", "initial", "TestData1.a-z.initial")] righ below the [DataSource...] attribute.
Rerun the coded test and check if it passes.
TestData1.a-z.Initial exist and is displayed. The declarative test works and iterates through this datasource successfully.
In your coded test, add the following line
[DataBinding("TestData1", "a-z", "initial", "TestData1.a-z.initial")] righ below the [DataSource...] attribute.
Rerun the coded test and check if it passes.
(The data source/table/column names might be case sensitive)
IT looks like for whatever reason the Databinding wasn't being created by the code generator, and is required.
Thanks for you help Yutong, you rock!