0

I am writing integration tests via unit tests by using Xunit. (the specific testing framework is not set in stone, Xunit is being used simply because it has been used before in this project team)

The integration tests will test the workings of an API that facilitates certain operations on AD accounts. We will be given a set of AD accounts that we can test. We will, among other things, test if we can successfully create and enable accounts. Set passwords. That kind of stuff.

Naturally I want to be able to prep these accounts before and roll them back after the tests are done. My first idea was to write custom attributes inheriting from BeforeAfterTestAttribute for every test and account. However, I am feeling not entirely comfortable with this approach.

We define 5 archetypes of account. Per archetype we further define 5 to 6 more sub types of accounts. In total we have 43 test accounts in AD. My approach would mean that I make either 43 x amount of tests attributes or 5 x amount of tests attributes if I group the prep and rollback of all subaccounts of an archetype together. Either way feels less than efficient.

All in all, the prep and rollback will be minimal things. Enabling/disabling/locking accounts. Deleting some, making sure others are there.

Is there a pattern that I can use for this instead?

1 Answer 1

3

Most problems in programming do not have patterns to solve them. The problems simply need to be solved using whichever tools you have at your disposal. At its root, this problem is about generating test data. There are as many ways to do this as there are programmers, and each way comes with its own benefits and drawbacks. You will need to assess each way for yourself given the requirements of your testing framework, the environment in which you run these tests, and the application behavior being tested.

Test data is usually generated in one of the following ways:

  • Before the entire test run
  • Before each test in some central "before test" event or callback.
  • As needed in each test, which would be part of the "Arrange" phase of the Arrange-Act-Assert pattern for testing.

Test data should be cleaned up in one of the same ways as listed above, just at the opposite end of a test:

  • In some central "after test run" event or callback.
  • In some central "after test" event or callback.
  • In the "cleanup" phase of a test, which would be executed after any assertions have been made, and after failures have been reported to the test runner. Each testing framework does this a little differently.

No matter which way you choose, your test code needs to keep track of the users it creates in Active Directory. Again, there are a zillion ways to do this which depend on how the data is created. Since you are creating data in another system, you have some additional considerations:

  • Use an isolated, dedicated instance of Active Directory so tests do not interfere with each others' data.
  • When using a shared instance of Active Directory, ensure that each user has a unique identifier which the test can refer to when it deletes this data.
  • Communication across a network is always slower than logic executed in memory. Creating 43 users before each test might go quickly for an individual test, but might become slow if you run 1,000 tests.

There is a lot to consider for these kinds of integration tests, and there is no design pattern that provides a silver bullet to solve all of these problems. You will need to decompose the problem of generating test data into smaller problems, and then solve those first.

1
  • Thank you for your answer. I marked this is the solution, in the end I am confined by the needs here, and will have to run very specific tests for each account individually.
    – Robin
    Jun 12, 2023 at 6:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.