Udostępnianie klas src / test między modułami w wielomodułowym projekcie Maven

120

Mam wielomodułowy projekt Mavena. Na potrzeby tego przykładu rozważ dwa moduły:

  • data
  • consumer

Moduł consumerma moduł datajako zależność.

Moduł datadeklaruje kilka podstawowych klas. Istnieją testy, src/testktóre z nich korzystają. Te testy wymagają długiego tworzenia obiektów, więc mam klasę z kilkoma metodami użytkowymi do tworzenia tych obiektów. Ta klasa narzędziowa ( SampleDataHelper) znajduje się w src/testhierarchii.

Mam też kilka testów w consumermodule, które wymagają stworzenia niektórych z tych długich obiektów. Chcę używać mojej SampleDataHelperklasy (zdefiniowanej w data src/test) w testach znajdujących się w moim consumer src/testdrzewie. Niestety, mimo że datajest to zależność consumer, consumernie można zobaczyć klas, które istnieją w ramach data src/test.

Aby temu zaradzić, pomyślałem, że mógłbym utworzyć kolejny moduł ( data-test) i przejść SampleDataHelperdo niego pod src/main. Następnie dodałbym data-testjako zależność zakresu testowegodata . Niestety, wprowadza to zależność cykliczną: dataużywa data-test, ale data-testtakże wymaga data.

Jedynym rozwiązaniem mam wymyślić ma miejsce SampleDataHelperpod data src/mainramach testpakietu i nadziei, że żaden prawdziwy kod aplikacji kiedykolwiek nazywa go.

Jak mogę udostępniać moje SampleDataHelperzajęcia między modułami bez umieszczania ich poniżej src/main?

Greg Kopff
źródło
1
Sprawdź tę odpowiedź . Myślę, że to powinno ci pomóc.
Andrew Logvinov,
7
Dla przyszłych czytelników: Przewodnik Mavena dotyczący korzystania z załączonych testów
Greg Kopff
@AndrewLogvinov: czy Twoja połączona odpowiedź nie wymagałaby „dwuetapowej” kompilacji? Aby najpierw zbudować i wdrożyć jeden moduł ( data), zanim będę mógł skompilować drugi moduł ( consumer).
Greg Kopff
Myślę, że może natknąć się pewne problemy, jeśli używasz mvn package, ale powinna działać dobrze w jednym etapie kompilacji podczas korzystania mvn installlub mvn deploy. Tylko krótka notatka. W jednym z naszych dużych projektów mamy opakowanie na junit TestBasei jest ono zlokalizowane, w src/mainktórym również nie uważam za dobry pomysł.
Andrew Logvinov,

Odpowiedzi:

152

Twój projekt konsumenta zależy od projektu danych, dlatego cieszymy się, że dane muszą zostać utworzone przed konsumentem. W rezultacie, korzystając z technik sugerowanych w komentarzach , upewnię się , że Twój projekt Data zawiera cały kod testowy, który chcesz udostępnić, i skonfiguruj POM do utworzenia testowego pliku JAR:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <version>2.2</version>
  <executions>
    <execution>
      <goals>
        <goal>test-jar</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Twój projekt konsumenta będzie wtedy zależał zarówno od normalnego artefaktu Data JAR, jak i dodatkowego test-jarartefaktu, z oczywiście zakresem testowym:

<dependency>
  <groupId>com.foo</groupId>
  <artifactId>data</artifactId>
  <version>1.0</version>
  <type>test-jar</type>
  <scope>test</scope>
</dependency>

Używałem tego podejścia przy wielu okazjach i działa dobrze.

Duncan Jones
źródło
1
dotyczące „Projekt Twojego konsumenta zależałby wtedy zarówno od normalnego artefaktu Data JAR, jak i dodatkowego artefaktu test-jar”, ​​kiedy dodam obie zależności danych do konsumenta (powiedzmy, że moje artefakty o nazwie data i konsumenci) pom, bez specyfikacji konkretnej wersji pom napotkał błąd. Dlaczego tak się dzieje?
Johnny
@StasS prawdopodobnie najlepiej będzie, jeśli otworzysz osobne pytanie na ten temat.
Duncan Jones
1

Problem w tym, że (niektóre) testy w datamodule zależą od SampleDataHelperklasy? Można przesunąć SampleDataHelperklasę do src/maintego data-testmodułu, jeśli w tym samym czasie przenieść testy (które zależą od konkretnej klasy) do src/testtego data-testmodułu. W konsekwencji nie byłoby więcej zależności cyklicznych.

matsev
źródło
1
Jeśli rozumiem, sugerujesz, aby wszelkie testy, które używają, SampleDataHelperzostały przeniesione z datamodułu lub consumermodułu (w stosownych przypadkach) do data-test. Niestety nie uważam tego za bardzo „zgrabne” rozwiązanie, ponieważ przenosi moje testy z testowanego modułu do innego. (Ściśle mówiąc, powiedziałeś tylko data, żebym przesunął testy, ale myślę, że poruszałbym się zarówno dla spójności). Ale dziękuję za odpowiedź. :-)
Greg Kopff
1
Tak, dobrze mnie zrozumiałeś. I prawdopodobnie jest to bardziej szybkie rozwiązanie niż zgrabne. :-)
matsev
Wyobrażam sobie, że te zależności pozostaną. Zakładając, że omawiane testy wykonują klasy zdefiniowane w projekcie Data, nadal musiałoby istnieć odwołanie do projektu Data z projektu Data-Test.
Duncan Jones
1
@DuncanJones Przepraszamy, w moim poście była mała literówka. Chodzi o to, że data-testmoduł powinien zależeć od datamodułu (a nie na odwrót). Aby uniknąć zależności cyklicznej, wszystkie testy, które obecnie znajdują się w datamodule używającym elementu, SampleDataHelpermuszą zostać przeniesione do data-testmodułu.
matsev
Rozumiem, to ma więcej sensu.
Duncan Jones