Gradle-bronsets

1. Overzicht

Bronsets bieden ons een krachtige manier om de broncode in onze Gradle-projecten te structureren.

In deze korte tutorial gaan we zien hoe we ze kunnen gebruiken.

2. Standaardbronsets

Voordat we naar de standaardinstellingen gaan, laten we eerst uitleggen wat bronsets zijn. Zoals de naam impliceert, bronsets vertegenwoordigen een logische groep van bronbestanden.

We behandelen de configuratie van Java-projecten, maar de concepten zijn ook van toepassing op andere Gradle-projecttypen.

2.1. Standaard projectlay-out

Laten we beginnen met een eenvoudige projectstructuur:

source-sets ├── src │ └── main │ ├── java │ │ ├── SourceSetsMain.java │ │ └── SourceSetsObject.java │ └── test │ └── SourceSetsTest.java └── build. gradle 

Laten we nu eens kijken naar het build.gradle:

pas plug-in toe: "java" description = "Voorbeeld van bronsets" test {testLogging {events "geslaagd", "overgeslagen", "mislukt"}} afhankelijkheden {implementatie ('org.apache.httpcomponents: httpclient: 4.5.12') testImplementation ('junit: junit: 4.12')}

De Java-plug-in gaat ervan uit src / main / java en src / test / java als standaard bronmappen.

Laten we een eenvoudige hulpprogramma-taak maken:

taak printSourceSetInformation () {doLast {sourceSets.each {srcSet -> println "[" + srcSet.name + "]" print "-> Brondirectory's:" + srcSet.allJava.srcDirs + "\ n" print "-> Uitvoer mappen: "+ srcSet.output.classesDirs.files +" \ n "println" "}}}

We printen hier slechts een paar eigenschappen van de bronset. We kunnen altijd de volledige JavaDoc bekijken voor meer informatie.

Laten we het uitvoeren en kijken wat we krijgen:

$ ./gradlew printSourceSetInformation> Taak: source-sets: printSourceSetInformation [main] -> Brondirectory's: [... / source-sets / src / main / java] -> Uitvoermappen: [... / source- sets / build / classes / java / main] [test] -> Brondirectory's: [... / source-sets / src / test / java] -> Uitvoermappen: [... / source-sets / build / classes / java / test] 

Merk op we hebben twee standaard bronsets: hoofd en test.

2.2. Standaardconfiguraties

De Java-plug-in maakt ook automatisch enkele standaard Gradle-configuraties voor ons.

Ze volgen een speciale naamgevingsconventie: .

We gebruiken ze om de afhankelijkheden in build.gradle:

afhankelijkheden {implementatie ('org.apache.httpcomponents: httpclient: 4.5.12') testImplementation ('junit: junit: 4.12')}

Merk op dat we specificeren implementatie in plaats van mainImplementation. Dit is een uitzondering op de naamgevingsconventie.

Standaard, testImplementation configuratie breidt zich uit implementatie en erft al zijn afhankelijkheden en outputs.

Laten we onze helper-taak verbeteren en kijken waar dit over gaat:

taak printSourceSetInformation () {doLast {sourceSets.each {srcSet -> println "[" + srcSet.name + "]" print "-> Brondirectory's:" + srcSet.allJava.srcDirs + "\ n" print "-> Uitvoer mappen: "+ srcSet.output.classesDirs.files +" \ n "print" -> Compileer klassenpad: \ n "srcSet.compileClasspath.files.each {print" "+ it.path +" \ n "} println" "} }}

Laten we de uitvoer eens bekijken:

[main] // zelfde output als voorheen -> Compile classpath: ... / httpclient-4.5.12.jar ... / httpcore-4.4.13.jar ... / commons-logging-1.2.jar .. ./commons-codec-1.11.jar [test] // zelfde output als voorheen -> Compileer klassenpad: ... / source-sets / build / classes / java / main ... / source-sets / build / resources / main ... / httpclient-4.5.12.jar ... / junit-4.12.jar ... / httpcore-4.4.13.jar ... / commons-logging-1.2.jar ... / commons- codec-1.11.jar ... / hamcrest-core-1.3.jar

De test source set bevat de uitgangen van hoofd in zijn compilatieklassenpad en omvat ook zijn afhankelijkheden.

Laten we vervolgens onze unit-test maken:

openbare klasse SourceSetsTest {@Test openbare leegte whenRun_ThenSuccess () {SourceSetsObject underTest = nieuwe SourceSetsObject ("lorem", "ipsum"); assertThat (underTest.getUser (), is ("lorem")); assertThat (underTest.getPassword (), is ("ipsum")); }}

Hier testen we een eenvoudige POJO die twee waarden opslaat. We kunnen het direct gebruiken omdat de hoofd outputs zijn in onze test klassenpad.

Laten we dit vervolgens vanuit Gradle uitvoeren:

./gradlew clean test> Taak: source-sets: test com.baeldung.test.SourceSetsTest> whenRunThenSuccess PASSED 

3. Aangepaste bronsets

Tot nu toe hebben we enkele verstandige standaardwaarden gezien. In de praktijk hebben we echter vaak aangepaste bronsets nodig, vooral voor integratietests.

Dat komt omdat we misschien alleen specifieke testbibliotheken willen hebben op het klassenpad van integratietests. We willen ze misschien ook onafhankelijk van unit-tests uitvoeren.

3.1. Aangepaste bronsets definiëren

Laten we een aparte bronmap maken voor onze integratietests:

source-sets ├── src │ └── main │ ├── java │ │ ├── SourceSetsMain.java │ │ └── SourceSetsObject.java │ ├── test │ │ └── SourceSetsTest.java │ └── itest │ └── SourceSetsITest.java └── build.gradle 

Laten we het volgende doen configureer het in ons build.gradle de ... gebruiken sourceSets construeren:

sourceSets {itest {java {}}} afhankelijkheden {implementatie ('org.apache.httpcomponents: httpclient: 4.5.12') testImplementation ('junit: junit: 4.12')} // andere verklaringen weggelaten 

Merk op dat we geen aangepaste directory hebben gespecificeerd. Dat komt omdat onze map overeenkomt met de naam van de nieuwe bronset (ik test).

Wij kunnen aanpassen welke mappen zijn opgenomen in het srcDirs eigendom:

sourceSets {itest {java {srcDirs ("src / itest")}}}

Herinner je je onze helper-taak vanaf het begin? Laten we het opnieuw uitvoeren en kijken wat het afdrukt:

$ ./gradlew printSourceSetInformation> Taak: source-sets: printSourceSetInformation [itest] -> Brondirectory's: [... / source-sets / src / itest / java] -> Uitvoermappen: [... / source- sets / build / classes / java / itest] -> Compileer klassenpad: ... / source-sets / build / classes / java / main ... / source-sets / build / resources / main [main] // same output als voorheen [test] // zelfde output als hiervoor

3.2. Specifieke afhankelijkheden aan de bronset toewijzen

Onthoud standaardconfiguraties? We krijgen nu enkele configuraties voor de ik test bron ingesteld.

Laten we gebruiken itestImplementation om een ​​nieuwe afhankelijkheid toe te wijzen:

afhankelijkheden {implementatie ('org.apache.httpcomponents: httpclient: 4.5.12') testImplementation ('junit: junit: 4.12') itestImplementation ('com.google.guava: guava: 29.0-jre')}

Deze is alleen van toepassing op integratietests.

Laten we onze vorige test aanpassen en deze toevoegen als een integratietest:

openbare klasse SourceSetsItest {@Test openbare leegte gegevenImmutableList_whenRun_ThenSuccess () {SourceSetsObject underTest = nieuwe SourceSetsObject ("lorem", "ipsum"); List someStrings = ImmutableList.of ("Baeldung", "is", "cool"); assertThat (underTest.getUser (), is ("lorem")); assertThat (underTest.getPassword (), is ("ipsum")); assertThat (someStrings.size (), is (3)); }}

In staat zijn om het uit te voeren, we moeten definieer een aangepaste testtaak die de gecompileerde outputs gebruikt:

// declaraties van bronsets // declaraties van afhankelijkheden taak itest (type: Test) {description = "Integratietests uitvoeren" group = "verificatie" testClassesDirs = sourceSets.itest.output.classesDirs classpath = sourceSets.itest.runtimeClasspath}

Deze verklaringen worden geëvalueerd tijdens de configuratiefase. Als resultaat, hun volgorde is belangrijk.

We kunnen bijvoorbeeld niet verwijzen naar de ik test source ingesteld in de hoofdtekst van de taak voordat dit wordt gedeclareerd.

Laten we eens kijken wat er gebeurt als we de test uitvoeren:

$ ./gradlew clean itest // enkele compilatieproblemen FAILURE: Build is mislukt met een uitzondering. * Wat ging er mis: uitvoering mislukt voor taak ': source-sets: compileItestJava'. > Compilatie mislukt; zie de compileerfoutuitvoer voor details.

In tegenstelling tot de vorige run krijgen we deze keer een compilatiefout. Dus wat gebeurde er?

Deze nieuwe bronset zorgt voor een onafhankelijke configuratie.

Met andere woorden, itestImplementation erft niet de JUnit afhankelijkheid, noch krijgt het de outputs van hoofd.

Laten we dit oplossen in onze Gradle-configuratie:

sourceSets {itest {compileClasspath + = sourceSets.main.output runtimeClasspath + = sourceSets.main.output java {}}} // afhankelijkheden declaratie configuraties {itestImplementation.extendsFrom (testImplementation) itestRuntimeOnly.extendsFrom (testRuntimeOnly)}

Laten we nu onze integratietest opnieuw uitvoeren:

$ ./gradlew clean itest> Taak: source-sets: itest com.baeldung.itest.SourceSetsItest> givenImmutableList_whenRun_ThenSuccess PASSED

De test slaagt.

3.3. Eclipse IDE-afhandeling

We hebben tot nu toe gezien hoe we rechtstreeks met Gradle met bronsets kunnen werken. Meestal gebruiken we echter een IDE (zoals Eclipse).

Wanneer we het project importeren, krijgen we enkele compilatieproblemen:

Als we echter de integratietest van Gradle uitvoeren, krijgen we geen fouten:

$ ./gradlew clean itest> Taak: source-sets: itest com.baeldung.itest.SourceSetsItest> givenImmutableList_whenRun_ThenSuccess PASSED

Dus wat gebeurde er? In dit geval is het guave afhankelijkheid behoort tot itestImplementation.

Helaas, de Eclipse Buildship Gradle-plug-in kan deze aangepaste configuraties niet zo goed aan.

Laten we los dit op in onze build.gradle:

pas plug-in toe: "eclipse" // vorige declaraties eclipse {classpath {plusConfigurations + = [configurations.itestCompileClasspath]}} 

Laten we uitleggen wat we hier hebben gedaan. We hebben onze configuratie toegevoegd aan het Eclipse-klassenpad.

Als we het project vernieuwen, zijn de compilatieproblemen verdwenen.

Echter, er is een nadeel aan deze benadering: De IDE maakt geen onderscheid tussen configuraties.

Dit betekent we kunnen gemakkelijk importeren guave in onze test bronnen (wat we specifiek wilden vermijden).

4. Conclusie

In deze zelfstudie hebben we de basisprincipes van Gradle-bronsets behandeld.

Vervolgens hebben we uitgelegd hoe aangepaste bronsets werken en hoe u ze in Eclipse kunt gebruiken.

Zoals gewoonlijk kunnen we de volledige broncode vinden op GitHub.


$config[zx-auto] not found$config[zx-overlay] not found