microsoft / testfx

MSTest framework and adapter
MIT License
749 stars 255 forks source link

Proper way of accessing TestContext.WriteLine from classes outside TestClass? #706

Open elgatov opened 4 years ago

elgatov commented 4 years ago

Hello,

I am using MSTest with selenium to run web tests.

Web testing promotes the Page Object Model to model a web page, abstracting what the test does from how it is done and promoting re-usability.

When running test serially, we can make use of Console.WriteLine from a PageObject class to let the test writer know important information about the test like variable values used and test flow, however the same approach cannot be taken when running in parallel as Console.WriteLine is redirected to the first test running.

A solution to this would be to pass TestContext to the PageObject class but this means that PageObject classes which normally only use a WebDriver parameter in their constructor would have to be refactored.

Another problem that arises is that a reference to MSTest has to be added on the project containing the PageObject classes to make use of TestContext.

We could try to avoid logging from PageObject and doing it only from test but if we have 100 tests and all of them have to log in the same page one would be tempted to avoid logging in each test and have the PageObject log in method do it for us.

Having said that my question is this: is passing TestContext as an argument the proper way to have access to TestContext from classes outside the TestClass? Is there another way to achieve this?

Thanks for your time.

martsve commented 4 years ago

You probably have to refactor your PageObjects. You could get around it with a static/singleton logger that uses the last used TestContext (set in the test initialization), but that would "break" for multi-threaded tests.

You should probably create a Logger/LoggerInterface that takes TestContext as a constructor-parameter. The logger/Interface can then be set in the constructor of your PageObjects. That way, your PageObjects are not dependent on the TestContext, and doesn't need to know how it logs the data.

elgatov commented 4 years ago

Hi @martsve and thanks for your input.

I already tried using a static/singleton but it breaks when running in parallel. I will probably take the second option of creating a Logger/LoggerInterface, however I would like some input from the testfx team too, maybe they know a proper way to do this.

Thanks for your response. 👍

nohwnd commented 4 years ago

I would do what @martsve suggests. Injecting an implementation of an interface into the SUT. That way the dependencies on test framework would stay in the test project.

StingyJack commented 3 years ago

There are also the Trace.Write*() tracing/logging methods. I can use them in the unit tests or in the code that is tested and they get captured into the correct test context as far as I can tell.

elgatov commented 3 years ago

There are also the Trace.Write*() tracing/logging methods. I can use them in the unit tests or in the code that is tested and they get captured into the correct test context as far as I can tell.

I thought this was not possible running in parallel. I will test it and report again. Thank you!

EDIT: no, the output of Trace is mapped to the first test executed, it is not being correctly captured by each test

Evangelink commented 9 months ago

@elgatov is there still some need for this?

elgatov commented 7 months ago

@Evangelink i had to add a whole logging library just to be able to have parallel logging capabilities and i would've loved if MSTest would've captured Debug/Trace and assigned it to it's corresponding test by default. i won't say it's a pressing matter but it would be nice for MSTest to have this out of the box

Evangelink commented 7 months ago

Debug/Trace and Console writes are captured and associated to the executed test. There were some bugs related to this feature and only recent versions are doing this relatively well. If you have some bugs related to this, please create some issue with repro so we can investigate.