Skip to content

Integration tests - TestNetworkService mock and server API split#337

Merged
timkimadobe merged 33 commits intoadobe:feature/upstream-integration-testsfrom
timkimadobe:integration-test-mock-real-split
May 18, 2023
Merged

Integration tests - TestNetworkService mock and server API split#337
timkimadobe merged 33 commits intoadobe:feature/upstream-integration-testsfrom
timkimadobe:integration-test-mock-real-split

Conversation

@timkimadobe
Copy link
Copy Markdown
Contributor

@timkimadobe timkimadobe commented May 11, 2023

Description

This PR migrates the network related APIs from TestBase -> TestNetworkService and where appropriate, the child classes MockTestNetworkService and ServerTestNetworkService.

With this change, there is a clear distinction between mock and server APIs and a reduction of redundant network validation code by relying on the shared base TestNetworkService class.

The key difference is that the static networkService instance is moved from TestBase to the test suite level.

The PR also demonstrates a proof of concept refactor in test usage for both functional and integration tests, with each test suite using the respective child class implementation of TestNetworkService:

  • Functional tests -> MockTestNetworkService
    • NOTE: all functional test files except for AEPEdgeFunctionalTests.swift have been removed temporarily, so that the functional test will build and run; once the approach is finalized, the other functional test files will be converted in this PR
  • Integration tests -> ServerTestNetworkService

Related Issue

Motivation and Context

How Has This Been Tested?

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • I have signed the Adobe Open Source CLA.
  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

private let EXPECTED_BASE_PATH = "https://ns.adobe.com/experience/mobilesdk/tvos"
#endif

private var networkService: MockTestNetworkService = MockTestNetworkService()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove the initialization here since it is being done in the setup.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screen Shot 2023-05-11 at 3 12 31 PM

I think I had tried not setting an initial value, but this was the error I encountered without the initialization

Copy link
Copy Markdown
Contributor

@addb addb May 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

few options:

  1. Make networkService optional
    private var networkService: MockTestNetworkService?
  2. Add init block
 init {
 networkService = MockTestNetworkService()
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed, updated to:

  1. Use static immutable variable to store network service
  2. Set it as the network service once in the class level setUp()


/// Reset event and network request expectations and drop the items received until this point
func resetTestExpectations() {
func resetTestExpectations(testNetworkService: TestNetworkService?) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If TestBase is not setting the network service then it should not reset it as well. With your changes, tests are setting the network service mock or server so they should reset it in their context.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok that definitely makes sense, I was thinking to keep it all in one line like before, but you're right that the responsibility of resetting networkService within TestBase doesn't make sense anymore

}

/// Equals compare based on host, scheme and URL path. Query params are not taken into consideration
func areNetworkRequestsEqual(lhs: NetworkRequest, rhs: NetworkRequest) -> Bool {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: We can also extend the NetworkRequest class and inherit Comparable to its definition and implement == (equals) function for it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe not, because of NetworkRequest's NSObject inheritance, we need to override the isEqual method in order for dictionaries etc. to use that for key uniqueness logic

However, overriding methods in class extensions requires min iOS 13+ which makes it impossible to add at the NetworkRequest class level, given our min iOS support

Screen Shot 2023-05-11 at 3 36 47 PM

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create a file in your test target Network+Equatable

extension NetworkRequest: Equatable {
static func == (lhs: NetworkRequest, rhs: NetworkRequest) -> Bool {
       //code
    }
}

let me know if this works.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screen Shot 2023-05-11 at 4 12 38 PM

This does work, but I believe because NetworkRequest inherits from NSObject, Dictionaries etc rely on the isEqual implementation, not the == operator definition
Please note:

  1. Removed the : Equatable since Xcode emitted warning that NetworkRequest already conformed to Equatable in its definition in AEPServices (I believe via its NSObject inheritance)
  2. I set a breakpoint on the body of the newly created == definition and ran the functional test suite, which should be triggered by MockTestNetworkService.connectAsync -> recordSentNetworkRequest where it sets the key + value in the sentNetworkRequests dictionary, if dictionary relies on this definition to compare keys. However, the breakpoint is never hit because I believe it is using the NSObject isEqual definition

Additional context:

  1. https://stackoverflow.com/questions/33319959/nsobject-subclass-in-swift-hash-vs-hashvalue-isequal-vs
  2. https://developer.apple.com/documentation/swift/dictionary#Bridging-Between-Dictionary-and-NSDictionary

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can at least add it to the NetworkRequest extension so usages can look like
func isEqual(_ other: NetworkRequest) -> Bool { .. }
usage: networkRequest.isEqual(otherNetworkRequest)

Copy link
Copy Markdown
Contributor Author

@timkimadobe timkimadobe May 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense to me! I was thinking if we are defining equality operators on NetworkRequest directly, between isEqual and ==, == is more Swifty. What do you think?

Also do you know if defining a custom == or isEqual overrides the base behavior for NetworkRequest everywhere? Like in AEPServices and Core, etc. That is, underlying business logic in other extensions etc?

If that's the case, maybe we should avoid the route of creating overrides for standard equality operators/methods? Since even though today it doesn't look like other extensions use isEqual/== for anything that could change in the future? Overriding them effectively means we're setting the contract that no one else will use equality checks on NetworkRequest

What are both your thoughts?

Edit: After looking at: https://stackoverflow.com/questions/28793218/swift-overriding-in-subclass-results-invocation-of-in-superclass-only
I think we're not really doing - or even expecting - a true equality (substitutability); in test cases we know that NetworkRequests are expected to be different but match the criteria in our custom equals
I feel that it's more of a group by criteria than an equals and maybe our method name should reflect that? ex: groupNetworkRequestsBy(criteria: NetworkRequest, toDetermine: NetworkRequest) (the names are not good, but just to give an example)

Edit 2: Actually giving it even more thought I think we should avoid creating two different types of equality that live under standard equals operators/methods - AEPServices is the one that sets the equality standard and if we want custom behavior (like for the purposes of this grouping) I think we should create a uniquely named method that specifies that:
isInGroup(), etc

Context: https://airspeedvelocity.net/2014/10/26/which-function-does-swift-call-part-4-generics/


let asyncTimeout: TimeInterval = 10

override class func setUp() {
Copy link
Copy Markdown
Contributor

@addb addb May 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this method as we dont do anything extra here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed!


public class override func setUp() {
super.setUp()
TestBase.debugEnabled = true
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to override this just to set this flag?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not totally sure, but I think not

the debugEnabled flag is only used in one place in the TestBase which is when it evaluates whether to output logs. Since the TestBase class override setUp() doesn't output any logs I've moved setting the flag to the FunctionalTest override setUp()

class UpstreamIntegrationTests: TestBase {
private var edgeEnvironment: EdgeEnvironment = .prod
private var edgeLocationHint: EdgeLocationHint?
private var networkService: ServerTestNetworkService = ServerTestNetworkService()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove init if we init it in the setup

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see #337 (comment)

/// Sets the mock `HttpConnection` response connection for a given `NetworkRequest`. Should only be used
/// when in mock mode.
///
/// - Returns: `true` if the response was successfully set.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again do we need this function?

also This method doesn't return anything at present.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see #337 (comment)

Also removed the return description from the method docs (this was a relic from the previous implementation)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes understood that. Wanted to make sure if we need to add a return or if not we should update the description.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For sure, sorry about that! I've also updated the description to remove the return portion

Update reset test expectations logic
Remove outdated method docs for return value
Update reset test expectations usage
Copy link
Copy Markdown
Contributor Author

@timkimadobe timkimadobe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much for the review @addb! Updated according to feedback with some outstanding questions

private let EXPECTED_BASE_PATH = "https://ns.adobe.com/experience/mobilesdk/tvos"
#endif

private var networkService: MockTestNetworkService = MockTestNetworkService()
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screen Shot 2023-05-11 at 3 12 31 PM

I think I had tried not setting an initial value, but this was the error I encountered without the initialization


private var networkService: MockTestNetworkService = MockTestNetworkService()

public class override func setUp() {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a great question, I'm not totally sure (this is an architecture that was in place when I started the shared test util updates) but based on some breakpoint investigation, it looks like the order of calls is:
(AEPEdgeFunctionalTests) class override setUp -> (TestBase) class override setUp
-> (AEPEdgeFunctionalTests) override setUp -> (TestBase) override setUp

Where the execution of the body depends on where the super.setUp() is placed

My understanding is that having both allows for interleaving operations between the child and parent class, so with this current setup you get:

  1. entrypoint: (AEPEdgeFunctionalTests) class override setUp - immediately calls 2
  2. (TestBase) class override setUp
  3. (AEPEdgeFunctionalTests) class override setUp - rest of the body
  4. (AEPEdgeFunctionalTests) override setUp - immediately calls 5
  5. (TestBase) override setUp
  6. (AEPEdgeFunctionalTests) override setUp - rest of the body


public class override func setUp() {
super.setUp()
TestBase.debugEnabled = true
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not totally sure, but I think not

the debugEnabled flag is only used in one place in the TestBase which is when it evaluates whether to output logs. Since the TestBase class override setUp() doesn't output any logs I've moved setting the flag to the FunctionalTest override setUp()

class UpstreamIntegrationTests: TestBase {
private var edgeEnvironment: EdgeEnvironment = .prod
private var edgeLocationHint: EdgeLocationHint?
private var networkService: ServerTestNetworkService = ServerTestNetworkService()
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see #337 (comment)

/// Sets the mock `HttpConnection` response connection for a given `NetworkRequest`. Should only be used
/// when in mock mode.
///
/// - Returns: `true` if the response was successfully set.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see #337 (comment)

Also removed the return description from the method docs (this was a relic from the previous implementation)

@codecov
Copy link
Copy Markdown

codecov bot commented May 11, 2023

Codecov Report

❗ No coverage uploaded for pull request base (feature/upstream-integration-tests@52aedff). Click here to learn what that means.
The diff coverage is n/a.

❗ Current head 49d7b75 differs from pull request most recent head bc2eb0c. Consider uploading reports for the commit bc2eb0c to get more accurate results

@@                          Coverage Diff                          @@
##             feature/upstream-integration-tests     #337   +/-   ##
=====================================================================
  Coverage                                      ?   96.61%           
=====================================================================
  Files                                         ?       28           
  Lines                                         ?     1650           
  Branches                                      ?        0           
=====================================================================
  Hits                                          ?     1594           
  Misses                                        ?       56           
  Partials                                      ?        0           

@addb
Copy link
Copy Markdown
Contributor

addb commented May 11, 2023

That is a great question, I'm not totally sure (this is an architecture that was in place when I started the shared test util updates) but based on some breakpoint investigation, it looks like the order of calls is:
(AEPEdgeFunctionalTests) class override setUp -> (TestBase) class override setUp
-> (AEPEdgeFunctionalTests) override setUp -> (TestBase) override setUp

Where the execution of the body depends on where the super.setUp() is placed

My understanding is that having both allows for interleaving operations between the child and parent class, so with this current setup you get:

entrypoint: (AEPEdgeFunctionalTests) class override setUp - immediately calls 2
(TestBase) class override setUp
(AEPEdgeFunctionalTests) class override setUp - rest of the body
(AEPEdgeFunctionalTests) override setUp - immediately calls 5
(TestBase) override setUp
(AEPEdgeFunctionalTests) override setUp - rest of the body

Yes, I thought so. That's why removed the comment. Is the class setup called once while executing all the steps? other setup would be called for each test.

We can confirm the behavior and revaluate if that ordering and different setup is required or we could clean that logic as well.

@timkimadobe
Copy link
Copy Markdown
Contributor Author

timkimadobe commented May 11, 2023

That is a great question, I'm not totally sure (this is an architecture that was in place when I started the shared test util updates) but based on some breakpoint investigation, it looks like the order of calls is:
(AEPEdgeFunctionalTests) class override setUp -> (TestBase) class override setUp
-> (AEPEdgeFunctionalTests) override setUp -> (TestBase) override setUp
Where the execution of the body depends on where the super.setUp() is placed
My understanding is that having both allows for interleaving operations between the child and parent class, so with this current setup you get:
entrypoint: (AEPEdgeFunctionalTests) class override setUp - immediately calls 2
(TestBase) class override setUp
(AEPEdgeFunctionalTests) class override setUp - rest of the body
(AEPEdgeFunctionalTests) override setUp - immediately calls 5
(TestBase) override setUp
(AEPEdgeFunctionalTests) override setUp - rest of the body

Yes, I thought so. That's why removed the comment. Is the class setup called once while executing all the steps? other setup would be called for each test.

We can confirm the behavior and revaluate if that ordering and different setup is required or we could clean that logic as well.

Oh I think you're right, the class func setUp() is called once per test suite run and the func setUp() is called before each test case

Since there are no TestBase logs in the class func setUp() that I can see, personally I think it would be fine to set the flag in the per-test-case setUp()

Edit: based on our discussion, moved the flag assignment to the class based setUp() since the network service assignment happens there too

Copy link
Copy Markdown
Contributor Author

@timkimadobe timkimadobe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the followup review @addb! Updated according to feedback

/// Sets the mock `HttpConnection` response connection for a given `NetworkRequest`. Should only be used
/// when in mock mode.
///
/// - Returns: `true` if the response was successfully set.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For sure, sorry about that! I've also updated the description to remove the return portion

private let EXPECTED_BASE_PATH = "https://ns.adobe.com/experience/mobilesdk/tvos"
#endif

private var networkService: MockTestNetworkService = MockTestNetworkService()
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed, updated to:

  1. Use static immutable variable to store network service
  2. Set it as the network service once in the class level setUp()

@timkimadobe timkimadobe requested a review from addb May 15, 2023 21:22
@timkimadobe timkimadobe mentioned this pull request May 15, 2023
10 tasks
Copy link
Copy Markdown
Contributor

@emdobrin emdobrin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, found few small cleanup items

}

// MARK: Network request response helpers
func getMockResponsesFor(networkRequest: NetworkRequest) -> [HttpConnection] {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be private and moved after internal functions

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated access level and position!

/// - See also:
/// - assertNetworkRequestsCount()
/// - getNetworkRequestsWith(url:httpMethod:)
func setExpectationForNetworkRequest(url: String, httpMethod: HttpMethod, expectedCount: Int32 = 1, file: StaticString = #file, line: UInt = #line) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good, should be ok to have a convenience API like this if they are used in pairs by the corresponding tests, e.g.
setExpectationForNetworkRequest(url, httpMethod, count...)
getNetworkRequestsWith(url, httpMethod...)

// Verify
// MARK: Network response assertions
let matchedResponsePost = getResponsesForRequestWith(url: "https://obumobile5.data.adobedc.net/ee/v1/interact", httpMethod: .post, timeout: 5)
let networkRequest = NetworkRequest(urlString: "https://obumobile5.data.adobedc.net/ee/v1/interact", httpMethod: .post)!
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can use this variable for both setExpectation and getResponsesFor

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds great to me! I'm planning on using this way in the test cases PR; if it's ok, I'll leave this implementation as is?

Copy link
Copy Markdown
Contributor Author

@timkimadobe timkimadobe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the review @emdobrin! Updated PR based on feedback, and also refactored all the existing functional test files using the new MockNetworkService

}

// MARK: Network request response helpers
func getMockResponsesFor(networkRequest: NetworkRequest) -> [HttpConnection] {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated access level and position!

// Verify
// MARK: Network response assertions
let matchedResponsePost = getResponsesForRequestWith(url: "https://obumobile5.data.adobedc.net/ee/v1/interact", httpMethod: .post, timeout: 5)
let networkRequest = NetworkRequest(urlString: "https://obumobile5.data.adobedc.net/ee/v1/interact", httpMethod: .post)!
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds great to me! I'm planning on using this way in the test cases PR; if it's ok, I'll leave this implementation as is?

Copy link
Copy Markdown
Contributor

@emdobrin emdobrin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, don't forget to squash

class UpstreamIntegrationTests: TestBase {
private var edgeEnvironment: EdgeEnvironment = .prod
private var edgeLocationHint: EdgeLocationHint?
// private static let networkService: ServerTestNetworkService = ServerTestNetworkService()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's remove commented code

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed!

@timkimadobe timkimadobe merged commit e85aeb9 into adobe:feature/upstream-integration-tests May 18, 2023
@timkimadobe timkimadobe deleted the integration-test-mock-real-split branch May 18, 2023 21:12
timkimadobe added a commit to timkimadobe/aepsdk-edge-ios that referenced this pull request Jun 13, 2023
…be#337)

* Move FTNS to shared test utils

* Rename FTNS to TNS

* Initial split of mock and server test network service implementations

Before removal of network logic from TestBase

* Migrate TestBase network APIs to TestNetworkService

Move mock or server specific APIs to respective child classes

* Update log source name

Update reset test expectations logic

* Remove resetting network service logic from test base

* Rename delayed network response param and var

Remove outdated method docs for return value

* Update setup logic

Update reset test expectations usage

* Update network service to static immutable var

Update usages to Self

* Remove todo as task is wont do

* Update mock response API param name

* Update integration test to use static network service

Also add helper comments to the purpose of the different setup methods

* Rename Server to Real TNS

Update base class inheritance for both mock and real TNS
Update base TNS to be a shared network request helper
Update usages within mock and real TNS to use new shared helper as instance var
Add passthrough APIs for both mock and real TNS to access helper methods as needed
Refactor static networkService in test class to instance to remove need for Self prefix
Update associated setUp logic
Add mock prefix to networkService in functional test for clarity

* Rename mock and real network service classes

* Clean up implementation

Update doc comment
Add implementation note for isEqual

* Move shared network service logic to helper

Update usage sites
Remove unused import

* Remove unused imports

* Move NetworkRequest flatten body method into NetworkRequest extension

Update usages

* Update access level

* Update doc class names

* Remove unneeded commented code

* Move testbase debug flag to per case setup

Update doc comment

* Refactor CompletionHandlerFunctionalTests to use MockNetworkService

* Refactor EdgeConsentTests to use MockNetworkService

* Add networkService reset

* Add NetworkService reset

* Refactor EdgePublicAPITests to use MockNetworkService

* Refactor AEPEdgePathOverwriteTests

Add test flow doc comments

* Refactor IdentityStateFunctionalTests

Move debug flag set to after setup

* Refactor NoConfigFunctionalTests

Update doc comment for what method is used to determine equality

* Refactor SampleFunctionalTests

* Apply lint autocorrect to PR files

* Remove unneeded commented code
timkimadobe added a commit to timkimadobe/aepsdk-edge-ios that referenced this pull request Jul 11, 2023
…be#337)

* Move FTNS to shared test utils

* Rename FTNS to TNS

* Initial split of mock and server test network service implementations

Before removal of network logic from TestBase

* Migrate TestBase network APIs to TestNetworkService

Move mock or server specific APIs to respective child classes

* Update log source name

Update reset test expectations logic

* Remove resetting network service logic from test base

* Rename delayed network response param and var

Remove outdated method docs for return value

* Update setup logic

Update reset test expectations usage

* Update network service to static immutable var

Update usages to Self

* Remove todo as task is wont do

* Update mock response API param name

* Update integration test to use static network service

Also add helper comments to the purpose of the different setup methods

* Rename Server to Real TNS

Update base class inheritance for both mock and real TNS
Update base TNS to be a shared network request helper
Update usages within mock and real TNS to use new shared helper as instance var
Add passthrough APIs for both mock and real TNS to access helper methods as needed
Refactor static networkService in test class to instance to remove need for Self prefix
Update associated setUp logic
Add mock prefix to networkService in functional test for clarity

* Rename mock and real network service classes

* Clean up implementation

Update doc comment
Add implementation note for isEqual

* Move shared network service logic to helper

Update usage sites
Remove unused import

* Remove unused imports

* Move NetworkRequest flatten body method into NetworkRequest extension

Update usages

* Update access level

* Update doc class names

* Remove unneeded commented code

* Move testbase debug flag to per case setup

Update doc comment

* Refactor CompletionHandlerFunctionalTests to use MockNetworkService

* Refactor EdgeConsentTests to use MockNetworkService

* Add networkService reset

* Add NetworkService reset

* Refactor EdgePublicAPITests to use MockNetworkService

* Refactor AEPEdgePathOverwriteTests

Add test flow doc comments

* Refactor IdentityStateFunctionalTests

Move debug flag set to after setup

* Refactor NoConfigFunctionalTests

Update doc comment for what method is used to determine equality

* Refactor SampleFunctionalTests

* Apply lint autocorrect to PR files

* Remove unneeded commented code
timkimadobe added a commit that referenced this pull request Jul 21, 2023
* Edge Network (Konductor) integration test with GitHub Action workflow (#321)

* initial e2e test

* update pods for e2e test target

* update workflow config settings

* implement pods cache to prevent high macos usage time

* Fix method typo in functional test helper

* test for locationHint

* Update integration test case

* Remove specific hint value

* update action to include build cache step

* update buildcache to upload logs for debug

* fix flag typo

* trying different cache system

* try with command line settings

* update to include key

* fix var bug in makefile command

* remove playground

* Remove build cache testing

* passing env vars to test target working

* Update e2e flow action, yaml, and test scheme for konductor env

* Fix action command to updated name

* Updating action text and defaults

* Update make command for e2e test to improve documentation

add conditional check warning output for KONDUCTOR_ENV

* update test names

* update job name

* Update env var extraction logic

* update test to use edge location hint

* update action to have location hint options

* fix github action var name

* Update makefile env vars and include edge location hint

* update makefile integration test docs

test colon in test run echo
update env var extraction documentation in test file

* update test output to use raw string values

* test using shell if else for job run id

* fix spacing syntax

* Update to user proper Edge Network name

* Update to EDGE_ENVIRONMENT

* Small doc updates

* Update documentation to correct links

* Update dropdown description

* Add quiet flag to xcodebuild command for integration test

* Rename integration test make command

Reorder position to under tvOS test

* Update name to UpstreamIntegrationTests

Test empty string option for dropdown

* Update action script to use updated make command

* Split enums into separate file, add env var extraction inits

* run pod install after new target name

* Remove FunctionalTestBase inheritance and unused compile sources

* Add validation for network request portion

* Rename and simplify IntegrationTestNetworkService to only required methods and properties

* Update to use raw multiline string instead of resource files

* Revert podfile lock version upgrade

* Update action job name to align with makefile name

* Update target name in makefile

* Remove extra newlines

Remove marketing version from integration test debug target build settings

* Remove implementation specific documentation

* Test spacing in makefile

* Test remove silent option

* test moving back to the bottom

* test updating command name

* test newline

* test name change again

* Revert all test name changes - the workflow error was not specifying the correct branch to run off of

* Add job failure help text

* Add doc comment to on failure step

* Revert changes in functional test utils

* Split test enums into separate files with shared util method

* Clean up comments and update test method

* Update EdgeEnvironment enum to have .prod default value

Update usage site in test setup

* Update to include xcresult visualizer tool

* Update with example test failure case

* Update env file ID to use helper method

Move NetworkTestingDelegate to network file

* Omit coverage from test results to save characters

* Fix clang flag warning from cocoapods

* Remove Xcode report tool step from this PR

* Update result bundle path to avoid name conflicts with other tests

* Add testing documentation comment hint

* Flexible JSON comparison system (#332)

* Implement JSON comparison system

* Update to use AEPServices AnyCodable

* Move assertion helpers to AnyCodableUtils

Update assertion methods to accept file and line args for inline errors on test failure
Update key path logic to pretty print

* Create flexible validation system, with exact match pathing

* Exact match wildcard example

* Update general wildcard logic to apply to all elements

Rename arguments and usage sites

* Complete revamp of flexible json comparison system

* Convert AnyCodable test assertion helpers to protocol with default implementations

Update test classes to adhere to new protocol and update usages
Update flexible assertion to use single method with parameter for default mode
Clean up code and update documentation for helper methods
Fix bug with escaped keys and add unit test case

* Apply swift lint

* Extract AnyCodable array extension into separate file

* Remove unused test setup methods

* Remove redundant test cases covered by AnyCodable unit tests

* Switch from protocol to XCTestCase extension

Update usages
Update documentation text

* Update keyPathAsString signature and usages

* Simplify implementation of AnyCodable array comparison

* Remove unused EventSpec

* Update filenames

Remove Bool return from assertEqual methods
Refactor to allow single public API for assertEqual

* Update flexible comparison APIs

* Add additional test cases for AnyCodable unit tests

* Apply swift lint formatting

* Update to use positive case

* Update method order

Update method signature styling

* Update actual condition

* Update flexible text setup to propagate file and line

Upgrade getCapturedRegexGroups to a test failure
Upgrade alternate path index errors to TEST ERROR, add file and line

* Fix incorrect find and replace

* Update regex capture to handle special cases

Add test cases that validate special cases

* Extract regex logic into shared function

* Update shared testing utilities for integration tests (#334)

* Move shared test files

* Refactor FunctionalTestBase and FunctionalTestNetworkService to allow for dual mode

This allows for sharing common test utilities between functional and integration tests

* Renaming all usages of FunctionalTestBase to updated name

* Rename mock mode bool

* Update method docs and cleanup code comments

* Update initializer param

Create separate data structs for mocked and real network responses
Update connectAsync logic structure

* Move XCTestCase+AnyCodableAsserts to shared test utils

Update method docs for TestNetworkService
Update mock bool in TestBase
Move AnyCodable helper methods to shared test utils

* Update TestConstants name and usages

* Consolidate networkResponses into single data struct

With mocked behavior controlled by mockNetworkService flag

* Update FunctionalTestConst usages

* Temporarily moving TestNetworkService for review

* Update set get logic for network responses

Consolidate awaitRequest logic
Simplify NetworkRequest construction
Use force unwrap for test constructions

* Move NetworkRequest extension to FTNS

* Integration tests - TestNetworkService mock and server API split (#337)

* Move FTNS to shared test utils

* Rename FTNS to TNS

* Initial split of mock and server test network service implementations

Before removal of network logic from TestBase

* Migrate TestBase network APIs to TestNetworkService

Move mock or server specific APIs to respective child classes

* Update log source name

Update reset test expectations logic

* Remove resetting network service logic from test base

* Rename delayed network response param and var

Remove outdated method docs for return value

* Update setup logic

Update reset test expectations usage

* Update network service to static immutable var

Update usages to Self

* Remove todo as task is wont do

* Update mock response API param name

* Update integration test to use static network service

Also add helper comments to the purpose of the different setup methods

* Rename Server to Real TNS

Update base class inheritance for both mock and real TNS
Update base TNS to be a shared network request helper
Update usages within mock and real TNS to use new shared helper as instance var
Add passthrough APIs for both mock and real TNS to access helper methods as needed
Refactor static networkService in test class to instance to remove need for Self prefix
Update associated setUp logic
Add mock prefix to networkService in functional test for clarity

* Rename mock and real network service classes

* Clean up implementation

Update doc comment
Add implementation note for isEqual

* Move shared network service logic to helper

Update usage sites
Remove unused import

* Remove unused imports

* Move NetworkRequest flatten body method into NetworkRequest extension

Update usages

* Update access level

* Update doc class names

* Remove unneeded commented code

* Move testbase debug flag to per case setup

Update doc comment

* Refactor CompletionHandlerFunctionalTests to use MockNetworkService

* Refactor EdgeConsentTests to use MockNetworkService

* Add networkService reset

* Add NetworkService reset

* Refactor EdgePublicAPITests to use MockNetworkService

* Refactor AEPEdgePathOverwriteTests

Add test flow doc comments

* Refactor IdentityStateFunctionalTests

Move debug flag set to after setup

* Refactor NoConfigFunctionalTests

Update doc comment for what method is used to determine equality

* Refactor SampleFunctionalTests

* Apply lint autocorrect to PR files

* Remove unneeded commented code

* Integration test cases (#346)

* Implementation notes

* WIP invalid datastream test

* Add test cases

Complex XDM, complex data
Preset location hint
expected error dataset ID
expected error invalid location hint

* Update setExpectation API to accept only NetworkRequest

Update docs
Update usages of updated API
Update networkService API usages in integration test class

* Clean up code comments

* Fix for unpassed params

* Update class docs

Add test note on how JSON comparison system works

* Apply swift lint autocorrect

* Rename vars and add additional assert on response count

Add changes lost in rebase

* Updated flexible JSON comparison notes

Refactored assertEdgeResonseHandle API and usages
Refactored location hint test case to use single variable for location hint value

* Update network service class docs

* Update first test case to have two event validation

* Remove unused API and refactor used API to call helper directly

* Update assertEdgeResponseHandle signature and usages

Create new helper methods to construct interact URLs with location hint

* Add strict count assertion for all responses

Update matchedResponses name to be uniform across test suite

* Update assertEdgeResponseError method to use getDispatchedEventsWith directly

Revert refactor of assertEdgeResponseHandle and usages
Add expectedCount argument to both APIs and update assertion logic to check all events
Add org ID related exact match assertions and exact match paths (non-wildcard)
Add exact match requirement for error type URL

* Remove unused API (actually)

* Update test cases to use direct assertions

* Refactor assert*Match APIs to non-nil expected AnyCodable

* Update assertExpectedEvents API to allow for custom timeout period

* Update to use conditional check on location hint if initial value is set

Simplify 2x event handle test case
Add longer timeout for event expectations

* Update test case setup

Remove outdated API comment

* Remove unused helper API

* Refactor functional tests from dev branch to use new testing utilities

* Use longer extension registration timeout

* Add per test case teardown network service reset

* Test extending teardown sleep duration

* Add higher timeout value for startup event validation

* Add sleep to allow more buffer for listener registration

* Extend setup timeout to 10s

* Restore original teardown sleep time

* Remove sleep from test case

* Change order of operations for test teardown

* Test unregistering instrumented extension in teardown process

* Add sleep to startup process to allow event hub setup time

* Add mock network service teardown to all functional tests

* Trigger CI workflow

* Revert changes in TestBase teardown

* Integration testing workflow update (#349)

* Add new integration test job

* Update device for integration to 8

* Update integration test job name

* Remove extra space

* Remove code coverage upload from integration job

* Test job conditional in circleci workflow

* Add non conditional step

* Update triggering branches

* Update initiating branch name condition to staging

* test fetching branch name from fork

* remove spaces from command

* Test extract both base and head branch names

* Add semicolons

* Update extraction commands

* Only fetch base branch name

Make integration setup steps non conditional

* Update job trigger conditions

* Update simulator for integration test to 14

* Update integration test workflow to use conditional at job level

* Update integration test job Xcode version

* Fix conditional in integration test job

* Move checkout step to non-conditional level

* Test current branch name also triggers integration test workflow

* Test branch name 2

* Remove test branch name

* Add main branch to check

* Update deployment version for integration target to 11

* Make integration test make command result output consistent with other tests

Add removal of existing old results part of the job like other tests

* Refactor to remove branch name conditionals from job level and use workflow job branch filter

* Test workflow job filter when set on current branch

* Update filter criteria

* Remove test branch filter

* Reorder jobs so conditional ones come after mandatory

* Update integration test target in podfile

---------

Co-authored-by: Emilia Dobrin <33132425+emdobrin@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Integration testing - Create testing utilities that simplify assertions

3 participants