سؤال

تخيل مشروع Java تم تصميمه باستخدام Maven الذي لدي:

  • بعض اختبارات الوحدات السريعة التي:
    • يجب أن يركض المطورون قبل الالتزام
    • يجب أن يعمل خادم CI الخاص بي (Hudson ، FWIW) عند اكتشاف التزام جديد ، مع إعطاء ملاحظات فورية تقريبًا في حالة الفشل
  • بعض اختبارات القبول الآلي البطيء:
    • يمكن للمطورين تشغيل إذا اختاروا ، على سبيل المثال ، لإعادة إنتاج وإصلاح الفشل
    • يجب أن يعمل خادم CI الخاص بي بعد إجراء اختبارات الوحدة بنجاح

هذا يبدو وكأنه سيناريو نموذجي. حاليا ، أنا أركض:

  • تختبر الوحدة في مرحلة "الاختبار"
  • اختبارات القبول في مرحلة "التحقق"

هناك نوعان من وظائف CI تم تكوينهما ، مشيرين إلى فرع VCS للمشروع:

  1. "مرحلة الالتزام" ، التي تدير "حزمة MVN" (ترجمة ووحدة اختبار الكود ، بناء قطعة أثرية) ، والتي إذا نجحت ، تدور:
  2. "اختبارات القبول الآلية" ، التي تدير "MVN تحقق" (إعداد وتشغيل وتهدم اختبارات القبول)

المشكلة هي أن وحدة Job 2 تختبر وتصنيع الاختبار القطع الأثرية مرة أخرى (لأن مرحلة التحقق تلقائيًا تستدعي مرحلة الحزمة). هذا غير مرغوب فيه لعدة أسباب (في تناقص الأهمية):

  • قد لا تكون القطع الأثرية التي أنشأتها Job 2 مطابقة لتلك التي تم إنشاؤها بواسطة Job 1 (على سبيل المثال إذا كان هناك التزام جديد في هذه الأثناء)
  • يطيل حلقة التغذية المرتدة للمطور الذي جعل الالتزام (أي يستغرق وقتًا أطول حتى يكتشفوا أنهم كسروا البناء)
  • يضيع الموارد على خادم CI

لذا فإن سؤالي هو ، كيف يمكنني تكوين Job 2 لاستخدام القطع الأثرية التي تم إنشاؤها بواسطة Job 1؟

أدرك أنه يمكنني فقط الحصول على وظيفة واحدة تدير "MVN التحقق" ، والتي من شأنها أن تنشئ القطع الأثرية مرة واحدة فقط ، لكنني أريد الحصول على وظائف CI منفصلة أعلاه من أجل تنفيذ خط أنابيب النشر على غرار فارلي.


في حال يساعد أي شخص ، إليك POM Full Maven 2 of "Project 2" في الإجابة المقبولة:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example.cake</groupId>
    <artifactId>cake-acceptance</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging>
    <name>Cake Shop Acceptance Tests</name>
    <description>
        Runs the automated acceptance tests for the Cake Shop web application.
    </description>
    <build>
        <plugins>
            <!-- Compiler -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
            <!-- Suppress the normal "test" phase; there's no unit tests -->
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.5</version>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
            <!-- Cargo (starts and stops the web container) -->
            <plugin>
                <groupId>org.codehaus.cargo</groupId>
                <artifactId>cargo-maven2-plugin</artifactId>
                <version>1.0.5</version>
                <executions>
                    <execution>
                        <id>start-container</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>start</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>stop-container</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>stop</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <!-- Don't wait for CTRL-C after starting the container -->
                    <wait>false</wait>

                    <container>
                        <containerId>jetty7x</containerId>
                        <type>embedded</type>
                        <timeout>20000</timeout>
                    </container>

                    <configuration>
                        <properties>
                            <cargo.servlet.port>${http.port}</cargo.servlet.port>
                        </properties>
                        <deployables>
                            <deployable>
                                <groupId>${project.groupId}</groupId>
                                <artifactId>${target.artifactId}</artifactId>
                                <type>war</type>
                                <properties>
                                    <context>${context.path}</context>
                                </properties>
                            </deployable>
                        </deployables>
                    </configuration>
                </configuration>
            </plugin>
            <!-- Failsafe (runs the acceptance tests) -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <id>integration-test</id>
                        <goals>
                            <goal>integration-test</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>verify</id>
                        <goals>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <includes>
                        <include>**/*Test.java</include>
                    </includes>
                    <skipTests>false</skipTests>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
            <!-- Add your tests' dependencies here, e.g. Selenium or Sahi,
                with "test" scope -->
        <dependency>
            <!-- The artifact under test -->
            <groupId>${project.groupId}</groupId>
            <artifactId>${target.artifactId}</artifactId>
            <version>${target.version}</version>
            <type>war</type>
        </dependency>
    </dependencies>
    <properties>
        <!-- The artifact under test -->
        <target.artifactId>cake</target.artifactId>
        <target.version>0.1.0-SNAPSHOT</target.version>
        <context.path>${target.artifactId}</context.path>
        <http.port>8081</http.port>
        <java.version>1.6</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
</project>

لاحظ أنه على الرغم من أن مشروع "الاختبارات" لا ينشئ قطعة أثرية ، فإنه يجب أن يستخدم نوعًا من العبوات (استخدمت "جرة" هنا) ، وإلا لا يتم إجراء أي اختبارات في مرحلة التحقق.

هل كانت مفيدة؟

المحلول

جرب مشروعين Maven. الأول يحتوي على اختبارات البناء والوحدة. تقوم بتثبيت القطع الأثرية في مستودعك المحلي. تدير الوظيفة الثانية مشروع Maven الثاني الذي يعلن عن القطع الأثرية للمشروع الأول باعتباره تبعيات ويدير الاختبارات الوظيفية.

لست متأكدًا مما إذا كان السيناريو الذي وصفته للتو ممكنًا ، لكنني أعتقد أنه كذلك.

لتحسين سريع يمكنك تجاوز اختبار الوحدة مع -Dmaven.test.skip=true. إذا قمت بتمرير رقم المراجعة للرمز الخاص بك في SCM إلى الوظيفة الثانية ، فيجب أن تكون قادرًا على الخروج من نفس رمز المصدر.

يمكنك أيضًا التحقق من البرنامج المساعد SCM Pace SCM Clone. قد يوفر لك هذا بعض الخيارات الإضافية.

نصائح أخرى

أعلم أن الأمر مضى وقت طويل ، لكن هذا ملموس بشكل جيد ولا يوجد أي من الإجابات تفعل ما تم طلبه ، لكنني وجدت شيئًا يعمل:

mvn failsafe:integration-test

هذا يدير الاختبارات مباشرة ، دون المرور عبر جميع الخطوات الوسيطة لبناء المشروع. قد ترغب في إضافة failsafe:verify بعد ذلك.

لذا فإن سؤالي هو ، كيف يمكنني تكوين Job 2 لاستخدام القطع الأثرية التي تم إنشاؤها بواسطة Job 1؟

لا يمكنك.

لا تحتاج إلى. ال مافن بناء دورة حياة هو الإعداد بطريقة تبدو وكأنها سوف تلبي احتياجاتك. سوف تدير دورة حياة الاختبار فقط الصعوبات السريعة. حزمة بناء حالتك النهائية دون تشغيل التحقق.

تحتاج فقط وظيفة CI واحدة. عندما تقوم CI بتشغيل دورة الحياة/تثبيت Maven ، إذا فشل Junits في فشل البناء ، فلن يتم تنفيذ البرامج النصية للتحقق.

يمكنك تحديد ملف تعريف Maven الذي سيتم استخدامه لتنفيذ اختبارات التكامل فقط. أفعل هذا كثيرا.

شيء من هذا القبيل:

<profiles>
    <profile>
        <id>integration</id>
        <activation>
            <activeByDefault>false</activeByDefault>
        </activation>
        <build>
            <plugins>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId><version>2.17</version>
                    <configuration>
                        <skipTests>true</skipTests>
                    </configuration>
                </plugin>
                <plugin>
                    <artifactId>maven-war-plugin</artifactId><version>2.4</version>
                    <configuration>
                        <outputDirectory>/tmp</outputDirectory>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

سوف تستدعي هذا مع:

mvn verify -Pintegration

لسوء الحظ ، لا يمكن تخطي البرنامج المساعد للحرب ، ولكن يمكنك إرسال إخراجه إلى مكان ما خارج الطريق (لقد استخدمت /TMP). إذا كنت ترغب حقًا في توفير milliseconds ، فيمكنك أيضًا تجاهل موارد الويب (باستثناء web.xml ، فلن يعمل بدون ذلك).

يمكنك أيضًا استخدام ملف التعريف لتخطي أي مكونات إضافية قد تكون تقوم بتشغيلها ، على سبيل المثال المكوّن الإضافي للتجميع ، Cobertura ، PMD ، إلخ.

ملف تعريف Maven الذي ينفذ اختبارات التكامل فقط (كما هو مقترح هنا) لا يكفي. تحتاج أيضًا إلى التأكد من أن تكوين Maven-Compiler-Plugin لديها useincrementalcompilation = false. تشغيل الملف الشخصي بهذه الطريقة ، لن يعيد تلقائيًا ، على سبيل المثال:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.3</version>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <useIncrementalCompilation>false</useIncrementalCompilation>
    </configuration>
</plugin>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top