Honestly, I find the description a bit confusing. Thus, I will take it bit by bit.
Basically, they have 2 big code bases/projects or assemblies which I would say assembly A and assembly B.

Also, we are having assembly Test A and assembly Test B.
I'll assume that Test A
depends on A
and Test B
depends on B
:

Test A is using some classes from assembly Test B

Test B is using some classes from assembly Test A

Test A is using some classes from assembly B

Ok, I can reason about that graph:
A
and B
are sinks (leaves if you prefer). In theory, you can deployed them separately. I'm guessing you deploy Test A
with A
and Test B
with B
and that is causing problems. Quick fix: Do not deploy tests.
There is a cycle: Test A
-> Test B
-> Test A
Originally I did some remarks on Test A
-> Test B
-> B
, Test A
-> B
, I'm scratching that, it is not relevant for this situation.
The cyclic dependency Test A
-> Test B
-> Test A
is the main concern. How to fix it is an economics question.
I was saying in the comments that you may allow code duplication, which you would have to refactor later. That was just the first thing that came to mind. Doing that, would increases technical debt, but allows you to archive the separation in less time. If you need to separate the projects right now, I would say you do this. If there is time, you can be more pragmatic.
To fix the cyclic dependency you need to understand that Test A
does not need Test B
, instead Test A
only needs a subset of Test B
. Similarly Test B
only needs a subset of Test A
.
Furthermore, we can say that both Test A
and Test B
need this subset. Borrowing from Bradley Uffner's comment I'll call TestCommon
.
You may start by creating an empty TestCommon
assembly, add the dependency to both Test A
and Test B
and start moving code there. Eventually you would be able to remove the dependencies from Test A
to Test B
and from Test B
to Test A
. There is a chance that a cyclic depenency would continue to exist inside of TestCommon
(without a detailed dependency diagram, I cannot tell). Regardless, extracting TestCommon
will result in code easier to maintain and reuse.
Extracting TestCommon
will result in the going from this:

To this:

Full diagram:

This is better. Now you can deploy Test B
and B
(and TestCommon
) without major problems. Yet, you still need to deploy B
with Test A
because it references it directly.
There is a link that goes from Test A
to B
. I will assume the more nuances case, which is where Test A
uses B
(I’ll explore the other cases later). Following same approach that we did to extract TestCommon
we would need to introduce another assembly. I will call it Utility
(I do not know what is in there, just that Test A
needs it), and will allow you to go from this:

To this:

At this point, we have separated the project successfully. We can see in the full diagram that it is possible to deploy Test A
and A
without Test B
and B
, and vice versa.
Full diagram:

To deploy A:

To deploy B:

¿What is Utility
?
Remember that Utility
was originally part of B
. It is the part of B
that we need to make Test A
work. Althought I do not know much about Utility
. Yet, I know what I do not know...
A. I do not know if Test A
uses or tests Utility
, I assume it uses it.
B. I do not know if Test B
uses or tests Utility
C. I do not know if B
need or not Utility
Let us explore the possible cases:
Test A
uses Utility
, Test B
uses Utility
, B
needs Utility
Utility
must be some suitability code that everybody uses to make things easier. A defect in Utility
would be a defect in both projects. Make tests for it in a new Test Utility
.
Test A
uses Utility
, Test B
uses Utility
, B
does not need Utility
Utility
is only needed for testing. Merge it into TestCommon
.
Test A
uses Utility
, Test B
tests Utility
, B
needs Utility
This is the more nuances of all cases...
B
and Test A
still both need this code... this code serves two masters Test A
and B
. This is not wrong. You can leave it as it is.
There is a risk that in the future you may want to introduce a change in Utility
for one of these projects, but that change introduces a bug in the other.
Right now the tests for Utility
are in Test B
, about which the people working on A
may not be worrying about. Therefore separating Test Utility
from Test B
is a good idea.
If, in the future, the requirements that Test A
and B
differ too much, there is a change that they will need two different solutions (at which point you can merge those into their respective projects).
Test A
uses Utility
, Test B
tests Utility
, B
does not need Utility
Remove the dependency B
has on Utility
and separate the tests for Utility
from Test B
into a new Test Utility
.
Test A
testsUtility
, Test B
uses Utility
, B
needs Utility
Test A
should not be testing code from B
. Migrate that code to Test B
and remove the dependency from Test A
to Utility
. You can now merge Utility
back into B
.
Test A
tests Utility
, Test B
uses Utility
, B
does not need Utility
Remove the dependency B
has on Utility
and separate the tests for Utility
from Test A
into a new Test Utility
.
Test A
tests Utility
, Test B
testsUtility
, B
needs Utility
The tests for Utility
are split in two. Extract them and put them in a new Test Utility
.
Test A
tests Utility
, Test B
tests Utility
, B
does not need Utility
Utility
is not being used. You may remove it along with its tests.
Final note: I made the diagrams using yUML.