I recently starting fiddling around with the Telerik Test Framework ( http://www.telerik.com/teststudio/testing-framework ).
I used this to set up automated browser tests.
At first i used them in classical test project in Visual Studio and everything worked fine.
Next i wanted to be able to use the automated browser outside of Visual Studio. So i create a console application where i used the framework for my automated browser, and everything worked fine.
Next i wanted to create a MVC project where i used the framework for the automated browser, and everything stopped working.
It seems like that for some reason when the automated browser is called from a web application that the selected browser won't start up.
The actual code were the automated browser is started is the same for the web app and the console app. Just different starting points.
I also don't get any errors about the browser not starting up, i simply end up with a time out exception from the framework after i want to launch the browser.
Console code:
namespace AutomatedTests
{
class Program
{
static void Main(string[] args)
{
var telerik = new TelerikTests();
telerik.TestLanguageCoockie();
}
}
}
Web application code:
namespace AutomatedTests.Controllers
{
public class BrowserTestController : Controller
{
public ActionResult Index()
{
var telerikTests = new TelerikTests();
telerikTests.TestLanguageCoockie();
}
}
}
TelerikTests code:
namespace AutomatedTests.Tests
{
[TestClass]
public class TelerikTests : BaseTest
{
private static Settings settings;
public TelerikTests()
{
Init();
}
private Manager createMyManager
{
get
{
return new Manager(settings); // = ArtOfTest.WebAii.Core.Manager
}
}
public void Init()
{
// Get basic settings.
settings = GetSettings(); // = BaseTest.GetSettings();
// Custumize away!
settings.Web.DefaultBrowser = BrowserType.Chrome;
settings.Web.KillBrowserProcessOnClose = true;
}
[TestMethod]
public void TestLanguageCoockie()
{
var myManager = createMyManager;
myManager.Start();
myManager.LaunchNewBrowser();
// More code to perform the actual test, but with the web app approach we never get past this. The browser doesn't start and a time out exception is thrown.
}
}
}
EDIT: It turns out that i have this issue for every browser, except IE. But i do need it working for the other browsers as well.
I ended up setting up a console project + a web application. The web application contacts the console application so that it can perform all the automated browser tasks. Later it send the information back to the web app so that it can send it back to the client.
Related
I have a very simple question.
Is it possible to run Nunit tests inside an asp.net web app?
Here is an example project:
MyApp -> ASP.Net app (.net5)
MyTests -> Nunit Tests (.net5)
My Asp.net project (MYApp) contains all my controllers and such, with a depency on NUnit.Engine and my test project.
There is another Test project (MyTests), which is just a dummy project.
I want to be able to run in a controller, inside my web app, my tests.
Example controller:
namespace MyApp.Controllers
{
[Route("api/tests")]
[ApiController]
public class TestController: ControllerBase
{
// Some helper class to verify everything is working somehow
private class ReportListener : ITestEventListener
{
public void OnTestEvent(string report)
{
Console.WriteLine(report);
}
}
[HttpGet]
public async Task<ActionResult> Trigger()
{
try
{
using ITestEngine engine = TestEngineActivator.CreateInstance();
engine.Initialize();
engine.WorkDirectory = Path.Combine(Directory.GetCurrentDirectory(), "../","MyTests/");
// Create a simple test package - one assembly, no special settings
TestPackage package = new TestPackage(#".\bin\Debug\net5.0\MyTests.dll"); //Just for debugging and testing
// Get a runner for the test package
using ITestRunner runner = engine.GetRunner(package);
runner.Load();
// Run all the tests in the assembly
XmlNode testResult = runner.Run(listener: new ReportListener(), TestFilter.Empty);
var outputs = Enumerable.Empty<string>();
foreach (XmlNode elem in testResult.SelectNodes("//test-case/output"))
{
outputs = outputs.Append(elem.InnerText);
}
}catch(Exception e)
{
}
return Ok();
}
}
}
But unfortunately all my attemps so far have failed.
Am I missing something?
Is Nunit.Engine not made to be run in an asp.net context?
I am building all this in .NET5.0 (company policy)
If needed I can provide an example project
There could be more, but one small thing would explain the failure...
The NUnit engine defaults to running tests in a separate process, which it launches. So, assuming that your code is working correctly as written, a ProcessRunner will be created and the engine will communicate with it, telling it to run your tests.
This could fail in one of two ways:
You may not have permission to create a process.
If you succeed in creating it, the code will definitely not be running in the asp.net context. In that case, it would probably error out and terminate with very little debug information provided.
A simple fix is to add a setting to the test package, telling the engine to run the tests in process.
TestPackage package = new TestPackage(#".\bin\Debug\net5.0\MyTests.dll");
package.AddSetting("ProcessModel", "InProcess");
If you get a second error after doing this, it should at least result in a clearer message and you should be able to debug through the code.
I have a solution that contains two projects the web application project and console application.
I call web API in the console application (in Program.cs class) and store the output in a list, and I want to display the list in my web form in the web application project. How can I call the function from Program.cs to my webform to display the result?
or if there is an easiest solution instead of this?
You can refer to the following steps to call console app functions in web forms.
First, please define the program.cs in your console app.
namespace TestConsole
{
public class Program
{
static void Main(string[] args)
{
}
public static List<string> Liststring()
{
List<string> list = new List<string>();
list.Add("test1");
list.Add("test2");
list.Add("test3");
list.Add("test4");
return list;
}
}
}
Second, In the web app, please click add-reference ->Projects-> Choose the console app.
Third, Please add the using statement in the top of the code.
Finally, you can use the following code to fill a list in the dropdownlist.
using System;
using System.Web.UI;
using TestConsole;
namespace WebApplication1
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
Dropdownlist1.DataSource = Program.Liststring();
Dropdownlist1.DataBind();
}
}
}
}
Result:
I assume that the Web API is you're calling from console application is an external one (not part of your web application).
I would have separated the logic reading from the Web API in a separate project and used that from both the console and web application.
I want to use Application Insights to log exceptions only. How can I do that?
I tried searching for ways turning other settings off such as this and it says that there is no way to turn it off.
I tried ITelemetryProcessor and encountered the same problem as this question. I tried both config and code ways of registering ITelemetryProcessor but it is not hit even if I explicitly throw an exception in my Web API controller.
I am using VS 2017 and created a new .Net Framework 4.6.2 Web API. I also have an InstrumentationKey and can see the exception logged in Azure portal.
First of all, the first link you referenced is nothing to do with your issue.
You want to only log the exceptions, but that link means that remove the old telemetry data like Trace in repository(where the telemetry data is stored after upload to app insights).
You can take use of ITelemetryProcessor to log exceptions only. Please follow my steps as below:
1.Add Application insights to your web api project by right clicking your project name -> select Configure Application Insights:
After SDK added, do not select the Enable trace collection:
2.Add a .cs file in your project, then implement your custom ITelemetryProcessor class, code is as below:
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.Extensibility;
namespace WebApplicationWebApi
{
public class ExceptionsFilter:ITelemetryProcessor
{
private ITelemetryProcessor Next { get; set; }
public ExceptionsFilter(ITelemetryProcessor next)
{
this.Next = next;
}
public void Process(ITelemetry item)
{
string s = item.GetType().Name;
//if it's not exception telemetry, just return without log it to app insights.
if (s != "ExceptionTelemetry")
{
return;
}
this.Next.Process(item);
}
}
}
3.Register your custom ITelemetryProcessor in the ApplicationInsights.config. In the node, add <Add Type="WebApplicationWebApi.ExceptionsFilter,WebApplicationWebApi"/> :
4.Then run your code. To make sure the custom ITelemetryProcessor class is called, you can set a breakpoint in that class to see if it's hit when running.
And for the testing purpose, I add some telemetry data in the HomeController.cs:
public class HomeController : Controller
{
TelemetryClient client = new TelemetryClient();
public ActionResult Index()
{
RequestTelemetry r1 = new RequestTelemetry();
r1.Name = "request message for testing";
client.TrackRequest(r1);
client.TrackTrace("trace message for testing wwwww.");
client.TrackException(new Exception("exception message for testing wwwww."));
ViewBag.Title = "Home Page";
return View();
}
}
5.In your visual studio output window, you should see these messages:
6.Then in visual studio, nav to Application Insights Search (in vs -> view -> other windows -> Application Insights Search), then check if there are some values here(if it has values like "4" in screenshot below, click on it):
7.If it has values in step 6, please click the update button, then check All:
8.Then you can see that only the Exceptions are logged:
I'm trying to play around with WebSockets on IIS 8.5. I started off with a couple of very basic C# classes from a lesson:
using Microsoft.Web.WebSockets;
using System.Web;
public class ChatHttpHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
if (context.IsWebSocketRequest)
context.AcceptWebSocketRequest(new WebSocketChatHandler());
}
public bool IsReusable
{
get { return true; }
}
}
public class WebSocketChatHandler : WebSocketHandler
{
private static WebSocketCollection clients = new WebSocketCollection();
private string name;
public override void OnOpen()
{
this.name = this.WebSocketContext.QueryString["username"];
clients.Add(this);
clients.Broadcast(string.Format("{0} joined.", name));
}
public override void OnMessage(string message)
{
clients.Broadcast(string.Format("{0}: {1}", name, message));
}
public override void OnClose()
{
clients.Remove(this);
clients.Broadcast(string.Format("{0} left.", name));
}
}
and a simple HTML client. The project builds ok, but when I try to connect to the handler, it returns error 500. The problem is that I cannot see what the exact error is, because neither Chrome nor FF load the response body for ws:// scheme, so i cannot even see it in the Network tab of Developer Tools (though IIS provides the body, as I can see from from the response' Content-Length).
Is there a way to see the response body in this situation? Or what am I missing with WebSockets in IIS?
The problem was with web.config.
I added
<httpRuntime targetFramework="4.5.1" />
to system.web section and it finally began to work
You should be able to see the cause of the error in the Windows Event Viewer.
Fiddler will show you the connection and that it has upgraded to web socket so you can use that tool to at least show you if the connection worked or not. I'm not aware of a tool which can show you the traffic flowing over the socket once it has been upgraded although there might be one.
Better still, debug it in Visual Studio with breakpoints and 'break on exception' set. You can tell VS to use IIS as the server by right clicking the web site and going to Property Pages then Start Options. Tick Use custom server and put your URL into the textbox. Click Specific page and choose your default page.
Comparing it to my working solution using the same DLL, I don't spot any obvious issues with the handling of the socket, so I would suggest commenting out this.name = this.WebSocketContext.QueryString["username"]; for now and replacing it with this.name = "TEST"; as that appears to be about the only code which deviates from the samples. Keep it simple until its working!
I have some integration tests where I want to verify certain requires are made against a third-[arty webserver. I was thinking I would replace the third-party server with a stub server that simply logs calls made to it. The calls do not need to succeed, but I do need a record of the requests made (mainly just the path+querystring).
I was considering just using IIS for this. I could 1) set up an empty site, 2) modify the system's host file to redirect requests to that site 3) parse the log file at the end of each test.
This is problematic as for IIS the log files are not written to immediately, and the files are written to continuosly. I'll need to locate the file, read the contents before the test, wait a nondeterministic amount of time after the test, read the update contents, etc.
Can someone think of a simpler way?
You could use the System.Net.HttpListener ( MSDN LINK ).
It works as embedded WebServer, this means you can even check the access on-the-fly without having to parse log files.
A class i used in my Code recently:
class Listener
{
private HttpListener listener = null;
public event EventHandler CommandReceived;
public Listener()
{
this.listener = new HttpListener();
this.listener.Prefixes.Add("http://localhost:12345/");
}
public void ContextReceived(IAsyncResult result)
{
if (!this.listener.IsListening)
{
return;
}
HttpListenerContext context = this.listener.EndGetContext(result);
this.listener.BeginGetContext(this.ContextReceived, this.listener);
if (context != null)
{
EventHandler handler = this.CommandReceived;
handler(context, new EventArgs());
}
}
public void Start()
{
this.listener.Start();
this.listener.BeginGetContext(this.ContextReceived, this.listener);
}
public void Stop()
{
this.listener.Stop();
}
}
Yeah, I don't think you need a whole webserver. You don't need to test HTTP.
What you do need to test is the underlying data structure that you're sending and receiving. So just create tests for that (i.e. make a point at which you can validate your generate dataformat with what is expected, and also with what you intend to receive, etc).
Test the data, not the protocol (unless, obviously, the protocol is custom).
I've done something very similar to this in a number of projects.
You don't want to create stubbed web service. That's just adding a dependency you don't need. What I did was create an interface which mimics the web service's API. I then created a proxy class that will call the web service in the live system. For testing I used RhinoMocks to create mocked classes that return the results I wanted to test for. This was very useful for me, as I could then produce all sorts of 'unexpected' behaviour which wouldn't be possible with the live system.
public interface IServiceFacade {
string Assignments();
}
public class ServiceFacade : IServiceFacade {
private readonly Service _service;
public ServiceFacade(Service service) {
_service = service;
}
public string Assignments() {
return _service.Assignments();
}
}
Then my test code contained stuff like this:
var serviceFacade = MockRepository.GenerateMock<IServiceFacade>();
serviceFacade.Stub(sf => sf.Assignments()).Return("BLAH BLAH BLAH");
or
serviceFacade.Stub(sf => sf.Assignments()).Return(null);
or
serviceFacade.Stub(sf => sf.Assignments()).Throw(new Exception("Some exception"));
I found this very useful.