একই জুনিট পরীক্ষাটি চালিয়ে যাওয়ার সহজ উপায়?


121

শিরোনামটির মতো, আমি ELipse ব্যবহার করে স্বয়ংক্রিয়ভাবে পরপর কয়েকবার JUnit 4.x পরীক্ষা চালানোর জন্য কিছু সহজ উপায় খুঁজছি।

একটি উদাহরণ একই পরীক্ষা পরপর 10 বার চালানো এবং ফলাফল ফিরে রিপোর্ট করা হবে।

আমাদের ইতিমধ্যে এটি করার একটি জটিল পদ্ধতি রয়েছে তবে আমি এটি করার একটি সহজ উপায় খুঁজছি যাতে আমি নিশ্চিত হয়ে উঠতে পারি যে আমি যে ফ্ল্যাঙ্ক টেস্টটি স্থির করে স্থির করার চেষ্টা করছি।

একটি আদর্শ সমাধান হ'ল আমি গ্রাহক একটি প্লাগইন / সেটিং / বৈশিষ্ট্য যা সম্পর্কে আমি অজানা।


5
আপনি কেন এটি করতে চান তা সম্পর্কে আমি খুব আগ্রহী।
বুহব

আমি একটি বড় ব্ল্যাক বক্স পরীক্ষা চালিয়ে যাচ্ছি, একটি ছোট পরিবর্তন করেছি এবং এটি দেখতে দেখতে চাই যে এটি কীভাবে পূর্ববর্তী ফ্ল্যাঙ্ক পরীক্ষার স্থায়িত্বকে প্রভাবিত করেছিল।
স্টিফান থাইবার্গ

এটি আসলে, ব্যর্থ হওয়া অবধি আপনি এটি চালানো চান তা বাদে, আমি কেবল এটি বেশ কয়েকবার চালাতে চাই, যা আমার উত্তরগুলিকে প্রভাবিত করতে পারে।
স্টিফান থাইবার্গ

4
আপনি কি টেস্টএনজির বিপক্ষে কারণ যদি তা না হয় তবে আপনি কেবল @ টেস্ট (ইনভোকেশনকাউন্ট = 10) ব্যবহার করতে পারতেন এবং এটি যা কিছু তা রয়েছে।
রবার্ট ম্যাসাওলি

1
আমি টেস্টএনজির "বিরুদ্ধে" ছিলাম না, আমরা এই প্রকল্পে এটি ব্যবহার করছিলাম না।
স্টিফান থাইবার্গ

উত্তর:


123

এটি করার সহজতম উপায় (অন্তত পরিমাণে নতুন কোডের প্রয়োজন হিসাবে) এটি করার জন্য প্যারামিট্রাইজড পরীক্ষা হিসাবে পরীক্ষা চালানো (একটিতে এনোটেট করা @RunWith(Parameterized.class)এবং 10 টি খালি প্যারামিটার সরবরাহ করার জন্য একটি পদ্ধতি যুক্ত করা)। এইভাবে কাঠামোটি 10 ​​বার পরীক্ষা চালাবে।

এই পরীক্ষাটি ক্লাসে একমাত্র পরীক্ষা হওয়া দরকার, বা সর্বোপরি সমস্ত পরীক্ষা পদ্ধতি ক্লাসে 10 বার চালানো উচিত।

এখানে একটি উদাহরণ:

@RunWith(Parameterized.class)
public class RunTenTimes {

    @Parameterized.Parameters
    public static Object[][] data() {
        return new Object[10][0];
    }

    public RunTenTimes() {
    }

    @Test
    public void runsTenTimes() {
        System.out.println("run");
    }
}

উপরেরটি দিয়ে, এটি পরামিতি-কম নির্মাণকারীর সাহায্যে করাও সম্ভব, তবে আমি নিশ্চিত নই যে কাঠামো লেখকরা এটির উদ্দেশ্য করেছিলেন, বা যদি ভবিষ্যতে এটি ভেঙে যায়।

আপনি যদি নিজের রানার বাস্তবায়ন করেন তবে আপনি রানারকে 10 বার পরীক্ষা চালাতে পারেন। আপনি যদি কোনও তৃতীয় পক্ষের রানার ব্যবহার করে থাকেন তবে 4.7 এর সাহায্যে আপনি নতুন @Ruleটিকাটি ব্যবহার করতে পারেন এবং MethodRuleইন্টারফেসটি প্রয়োগ করতে পারেন যাতে এটি বিবৃতি গ্রহণ করে এবং লুপের জন্য এটি 10 ​​বার কার্যকর করে। এই পদ্ধতির বর্তমান অসুবিধা যে @Beforeএবং @Afterশুধুমাত্র একবার চালানো হয়। এটি সম্ভবত ইউনাইটের পরবর্তী সংস্করণে পরিবর্তিত হবে (এর @Beforeপরে চলবে @Rule), তবে আপনি বস্তুর একই উদাহরণে অভিনয় করবেন (এমন কিছু যা Parameterizedরানারের ক্ষেত্রে সত্য নয় )। এটি ধরে নেওয়া হয় যে আপনি যে ধরণের রানার সাথে ক্লাস চালাচ্ছেন তা @Ruleটীকাগুলিকে সঠিকভাবে স্বীকৃতি দেয় । এটি কেবলমাত্র যদি এটি ইউনাইট রানারদেরকে অর্পণ করে।

আপনি যদি এমন কোনও কাস্টম রানার নিয়ে @Ruleছুটে চলেছেন যা টীকাটি স্বীকৃতি দেয় না , তবে আপনি নিজের রানার লিখতে গিয়ে আটকে আছেন যা সেই রানারকে যথাযথভাবে প্রতিনিধিত্ব করে এবং 10 বার এটি চালায়।

নোট করুন যে এটির সম্ভাব্য সমাধানের অন্যান্য উপায় রয়েছে (যেমন থিওরিজ রানার) তবে তাদের সবার জন্য রানার প্রয়োজন। দুর্ভাগ্যক্রমে JUnit বর্তমানে রানার স্তরগুলি সমর্থন করে না। এটি এমন একটি রানার যা অন্য রানারদের শিকল দেয়।


2
দুর্ভাগ্যক্রমে আমি ইতিমধ্যে অন্য রানার সাথে @ রনউইথ চালিয়ে যাচ্ছি তবে অন্যথায় এটি একটি আদর্শ সমাধান হতে পারত।
স্টিফান থাইবার্গ

হ্যাঁ, এটি এমন সমাধান যা আমি চাই এবং যা বেশিরভাগ মানুষের পক্ষে সবচেয়ে ভাল হবে তাই আমি এগিয়ে যাব এবং উত্তরটি গ্রহণ করব।
স্টিফান থাইবার্গ

একটি বিকল্প এবং সম্ভবত কম হল hacky সমাধান দেখুন: stackoverflow.com/a/21349010/281545
Mr_and_Mrs_D

চমৎকার সমাধান! ডেটা পদ্ধতিতে অ্যারেগুলির একটি আইটেবল ফিরিয়ে দেওয়া উচিত বলে আমাকে ব্যতিক্রম পেয়েছিল। আমি সে অনুযায়ী এটি ঠিক করেছি: @ প্যারামিটারাইজড P }
নাদ্রে

1
আপনি দয়া করে 5 উত্তর জন্য এই উত্তর লিঙ্ক করতে পারেন ? এটি অনুরোধ করা বৈশিষ্ট্যটি বর্ণনা করে যা
জুনেট

100

ইন্টেলিজের সাহায্যে আপনি পরীক্ষা কনফিগারেশন থেকে এটি করতে পারেন। একবার আপনি এই উইন্ডোটি খোলার পরে, আপনি যতবার চান পরীক্ষা চালানোর জন্য চয়ন করতে পারেন ,.

এখানে চিত্র বর্ণনা লিখুন

আপনি যখন পরীক্ষা চালান, ইন্টেলিজ আপনি নির্দিষ্ট সময়ের জন্য নির্বাচিত সমস্ত পরীক্ষা সম্পাদন করবেন।

10 বার 624 পরীক্ষা চালানোর উদাহরণ: এখানে চিত্র বর্ণনা লিখুন


4
এটি নিখুঁত, এখন আপনি যদি এটি করার কোনও গ্রহগ্রন্থের দিকে ইঙ্গিত করতে পারেন তবে এটি ওপেনের প্রশ্নের উত্তরটি দেবে
খাল

প্রকৃত যুক্তি বা প্রয়োজনীয়তাগুলি হোস্ট করার জন্য একটি নির্দিষ্ট সরঞ্জামের উপর নির্ভর করা একটি বিরোধী-নিদর্শন।
মিকেল

1
@ মিকায়েল একটি পরীক্ষা এন বার পুনরাবৃত্তি করা সাধারণত পরীক্ষার প্রয়োজন হয় না। প্রকৃতপক্ষে পরীক্ষাগুলি নির্দ্বিধায় হওয়া উচিত, যাতে এটি বারবার পুনরাবৃত্তি না করেই সর্বদা একই ফল পাওয়া উচিত। আপনি যে অ্যান্টি প্যাটার্নটির কথা বলছেন তা ব্যাখ্যা করতে পারেন?
স্ম্যাক 89

যদি কোনও পরীক্ষার পুনরাবৃত্তি করা 1 বিকাশকারীদের পক্ষে কার্যকর হয়, তবে এটি অন্যদের পক্ষে সম্ভবত কার্যকর। সুতরাং যদি পরীক্ষার রানটাইম এবং কোডটি পুনরাবৃত্তি সক্ষম করতে লজিককে হোস্ট করতে পারে, তবে এটি পছন্দ করা উচিত কারণ এটি প্রচেষ্টা এবং সমাধানকে ফ্যাক্টর করতে এবং অবদানকারীদের একই ফলাফলের সাথে সরঞ্জামটি ব্যবহার করতে দেয়। কোডে রাখা যেতে পারে যখন আইডিই / বিকাশকারী অঞ্চলে পুনরায় ব্যবহারযোগ্য যুক্তি স্থাপন করা একধরনের অনুপস্থিত কারণ।
মিকেল

68

আমি খুঁজে পেয়েছি যে স্প্রিংয়ের পুনরাবৃত্তি টীকাগুলি এই ধরণের জিনিসটির জন্য দরকারী:

@Repeat(value = 10)

সর্বশেষ (স্প্রিং ফ্রেমওয়ার্ক 4.3.11. রিলিজ এপিআই) ডক:


46
পরীক্ষার ফ্রেমওয়ার্কগুলি পরিবর্তন করা আমি একে এটি করার সহজ উপায় বলি না।
স্টিফান থাইবার্গ

3
আপনাকে আপনার পরীক্ষার কাঠামো পরিবর্তন করতে হবে না - এটি JUnit এর সাথে কাজ করে। মূল অসুবিধা হ'ল জুনিত এখনও এটিকে একক পরীক্ষারূপে দেখে। সুতরাং এটি প্রথমবার ভাঙ্গলে মৃত্যুদন্ড কার্যকর হবে। তবে আপনি যদি ইতিমধ্যে স্প্রিং ব্যবহার না করে থাকেন তবে সম্ভবত আপনি যেভাবে যেতে চান তা নয় ...
tveon

আমার জন্য কাজ করছে বলে মনে হচ্ছে না (স্প্রিং বুট 1.5.1.1 এর মাধ্যমে স্প্রিং 4.3.6)
ডেভিড টনহোফার

বসন্ত বুট 2.1.6 এবং junit 5 আমার জন্য কাজ করে না
jo-

পোস্টারের 'বসন্তে ইউনিট পরীক্ষার' লিঙ্ক অনুসারে @ রনউইথ (স্প্রিংআরনার :: ক্লাস) যুক্ত করতে ভুলবেন না!
আগস্টন হরভাথ

33

নিম্নলিখিত সংস্থান থেকে অনুপ্রাণিত:

উদাহরণ

নীচে @Repeatহিসাবে একটি টীকা তৈরি করুন এবং ব্যবহার করুন :

public class MyTestClass {

    @Rule
    public RepeatRule repeatRule = new RepeatRule();

    @Test
    @Repeat(10)
    public void testMyCode() {
        //your test code goes here
    }
}

Repeat.java

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.METHOD;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention( RetentionPolicy.RUNTIME )
@Target({ METHOD, ANNOTATION_TYPE })
public @interface Repeat {
    int value() default 1;
}

RepeatRule.java

import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

public class RepeatRule implements TestRule {

    private static class RepeatStatement extends Statement {
        private final Statement statement;
        private final int repeat;    

        public RepeatStatement(Statement statement, int repeat) {
            this.statement = statement;
            this.repeat = repeat;
        }

        @Override
        public void evaluate() throws Throwable {
            for (int i = 0; i < repeat; i++) {
                statement.evaluate();
            }
        }

    }

    @Override
    public Statement apply(Statement statement, Description description) {
        Statement result = statement;
        Repeat repeat = description.getAnnotation(Repeat.class);
        if (repeat != null) {
            int times = repeat.value();
            result = new RepeatStatement(statement, times);
        }
        return result;
    }
}

PowerMock

এই সমাধানটি এর সাথে ব্যবহার @RunWith(PowerMockRunner.class)করার জন্য পাওয়ারমক 1.6.5 (যার মধ্যে একটি প্যাচ রয়েছে ) আপডেট করা দরকার ।


হ্যাঁ. আপনি কিভাবে পরীক্ষা চালাচ্ছেন?
আর ওস্টারহোল্ট

আমি নিজেই গ্রহনটি ব্যবহার করছি না। আপনি কি জুনট 4 টেস্ট রানার ব্যবহার করছেন না? ( ডক "কাস্টমাইজিং এ টেস্ট কনফিগারেশন" দেখুন )
আর ওস্টারস্টার হোল

29

JUnit 5 এর সাহায্যে আমি @ পুনর্বার টেস্ট টীকাটি ব্যবহার করে এটি সমাধান করতে সক্ষম হয়েছি :

@RepeatedTest(10)
public void testMyCode() {
    //your test code goes here
}

নোট করুন যে @Testটীকাটি পাশাপাশি ব্যবহার করা উচিত নয় @RepeatedTest


খুব প্রতিশ্রুতিবদ্ধ শোনায়, কেবলমাত্র এখনও প্রকাশের কোনও সংস্করণ নেই তা লক্ষ করার জন্য।
9 বিএসডিএক্স 9 আরভিজে 0lo

1
কয়েক সপ্তাহ আগে JUnit 5 জিএ-তে আঘাত করেছিল।
এমকোবিট

11

এর সাথে যে কোনও সমস্যা:

@Test
void itWorks() {
    // stuff
}

@Test
void itWorksRepeatably() {
    for (int i = 0; i < 10; i++) {
        itWorks();
    }
}

আপনি প্রতিটি মানগুলির একটি অ্যারে পরীক্ষা করছেন এমন ক্ষেত্রেের বিপরীতে, আপনি বিশেষত যত্নবান হন না যে কোনটি ব্যর্থ হয়েছিল।

আপনি কোডে যা করতে পারেন তা কনফিগারেশন বা টীকায়িত করার দরকার নেই।


2
আমি সাধারণ ইউনিট পরীক্ষা হিসাবে বেশ কয়েকটি পরীক্ষা চালাতে চাই এবং প্রত্যেকটির জন্য একটি ট্রেস এবং স্থিতি পেতে চাই।
স্টিফান থাইবার্গ

24
এক্ষেত্রে "@ পূর্ব" গুলি এবং "@ পরে" গুলি চালানো হবে না
বোগদান

3
এটি আমার সমস্যা সমাধানের @Beforeআগে ম্যানুয়ালি টীকাযুক্ত পদ্ধতিতে কল করার পাশাপাশি calling itWorks()
জোওো নেভেস

আপনি DRY ধারণা জানেন? en.wikedia.org/wiki/Don%27t_repeat_your সহায়ক আমি আপনার লুপটি যে কোনও জায়গায় আটকে দেবার পরিবর্তে কিছু সেটআপ করার পরামর্শ দিচ্ছি।
কিকিওয়া

এই উত্তরের সম্পাদনা সারি পূর্ণ; অতএব, আমি এটি একটি মন্তব্যে রাখব: JUnit4 এর জন্য, পরীক্ষাগুলি সর্বজনীন হওয়া দরকার।
রিচার্ড জেসোপ

7

এটি আমার পক্ষে অনেক সহজ কাজ করে।

public class RepeatTests extends TestCase {

    public static Test suite() {
        TestSuite suite = new TestSuite(RepeatTests.class.getName());

        for (int i = 0; i < 10; i++) {              
        suite.addTestSuite(YourTest.class);             
        }

        return suite;
    }
}

অপূর্ব হিসাবে অন্য কাঠামো ব্যবহার করে না এবং আসলে JUnit 3 (অ্যান্ড্রয়েডের জন্য গুরুত্বপূর্ণ) এর সাথে কাজ করে
ভ্লাদিমির ইভানভ

1
একটি রানার দিয়ে JUnit4 এর সাথে একটি বাস্তবায়ন করা যেতে পারে: public class RepeatRunner extends BlockJUnit4ClassRunner { public RepeatRunner(Class klass) throws InitializationError { super(klass); } @Override public void run(final RunNotifier notifier) { for (int i = 0; i < 10; i++) { super.run(notifier); } } }যদিও কমপক্ষে Eclipse JUnit প্লাগইনে আপনার ফলাফল পাবেন: "10/1 পরীক্ষা পাস হয়েছে"
পিটার উইপ্পারম্যান

7

টেম্পাস-ফুগিত লাইব্রেরিতে একটি অন্তর্বর্তী টীকা রয়েছে যা JUnit 4.7 এর @Ruleসাথে কয়েকবার পরীক্ষার পুনরাবৃত্তি করতে বা তার সাথে কাজ করে @RunWith

উদাহরণ স্বরূপ,

@RunWith(IntermittentTestRunner.class)
public class IntermittentTestRunnerTest {

   private static int testCounter = 0;

   @Test
   @Intermittent(repition = 99)
   public void annotatedTest() {
      testCounter++;
   }
}

পরীক্ষাটি পরিচালনার পরে (এর মধ্যে ইন্টারমিটেন্টটেস্ট রুনার সহ @RunWith) testCounter99 এর সমান হবে।


হ্যাঁ, এটি এখানে একই সমস্যা, ইতিমধ্যে অন্য রানার ব্যবহার করছে এবং এটি এইটিকে ব্যবহার করতে পারে না, যদিও ভাল ধারণা।
স্টিফান থাইবার্গ

হ্যাঁ, রানওথের সাথে আমারও একই সমস্যা রয়েছে ... আমি যখন টেম্পস-ফুগিটকে কিছুটা গোল করে দেখতে পেরেছি, আপনি বারবার দৌড়াতে চাইলে আপনি রানারের চেয়ে @ রুল ব্যবহার করতে পারেন। আপনি এটি বিরতি ছাড়াই @ পুনর্বার সাথে চিহ্নিত করুন। নিয়ম সংস্করণটি @ এর আগে / @ আফটারদের পরে চলবে না। আরও তথ্যের জন্য টেম্পস- fugit.googlecode.com/svn/site/docamentation/… (লোড / ভেজানো পরীক্ষার জন্য নীচে স্ক্রোল করুন) দেখুন।
টবি

0

আমি এমন একটি মডিউল তৈরি করি যা এই ধরণের পরীক্ষার অনুমতি দেয় allows তবে এটি কেবল পুনরাবৃত্তিতেই নিবদ্ধ নয়। তবে গ্যারান্টিতে যে কোডের কিছু অংশ থ্রেড নিরাপদ।

https://github.com/anderson-marques/concurrent-testing

মাভেন নির্ভরতা:

<dependency>
    <groupId>org.lite</groupId>
    <artifactId>concurrent-testing</artifactId>
    <version>1.0.0</version>
</dependency>

ব্যবহারের উদাহরণ:

package org.lite.concurrent.testing;

import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import ConcurrentTest;
import ConcurrentTestsRule;

/**
 * Concurrent tests examples
 */
public class ExampleTest {

    /**
     * Create a new TestRule that will be applied to all tests
     */
    @Rule
    public ConcurrentTestsRule ct = ConcurrentTestsRule.silentTests();

    /**
     * Tests using 10 threads and make 20 requests. This means until 10 simultaneous requests.
     */
    @Test
    @ConcurrentTest(requests = 20, threads = 10)
    public void testConcurrentExecutionSuccess(){
        Assert.assertTrue(true);
    }

    /**
     * Tests using 10 threads and make 20 requests. This means until 10 simultaneous requests.
     */
    @Test
    @ConcurrentTest(requests = 200, threads = 10, timeoutMillis = 100)
    public void testConcurrentExecutionSuccessWaitOnly100Millissecond(){
    }

    @Test(expected = RuntimeException.class)
    @ConcurrentTest(requests = 3)
    public void testConcurrentExecutionFail(){
        throw new RuntimeException("Fail");
    }
}

এটি একটি ওপেন সোর্স প্রকল্প। উন্নতি নির্দ্বিধায়।


0

আপনি একটি প্রধান পদ্ধতি থেকে আপনার JUnit পরীক্ষা চালাতে পারেন এবং এটি আপনার প্রয়োজন যতবার পুনরাবৃত্তি করতে পারেন:

package tests;

import static org.junit.Assert.*;

import org.junit.Test;
import org.junit.runner.Result;

public class RepeatedTest {

    @Test
    public void test() {
        fail("Not yet implemented");
    }

    public static void main(String args[]) {

        boolean runForever = true;

        while (runForever) {
            Result result = org.junit.runner.JUnitCore.runClasses(RepeatedTest.class);

            if (result.getFailureCount() > 0) {
                runForever = false;
               //Do something with the result object

            }
        }

    }

}

0

কোশলিনে যিশাই উপরোক্ত যে উত্তরটি দিয়েছেন তা মূলত:

@RunWith(Parameterized::class)
class MyTest {

    companion object {

        private const val numberOfTests = 200

        @JvmStatic
        @Parameterized.Parameters
        fun data(): Array<Array<Any?>> = Array(numberOfTests) { arrayOfNulls<Any?>(0) }
    }

    @Test
    fun testSomething() { }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.