JUnit 4 এ বর্তমানে পরীক্ষা চালানোর নাম পান


240

জুনেটে 3 তে, আমি বর্তমানে চলমান পরীক্ষার নামটি পেতে পারি:

public class MyTest extends TestCase
{
    public void testSomething()
    {
        System.out.println("Current test is " + getName());
        ...
    }
}

যা "বর্তমান পরীক্ষা টেস্টসোমথিং" মুদ্রণ করবে।

ইউনাইট 4-এ এটি করার কোনও বাক্স-অফ-দ্য বাক্স বা সহজ উপায় আছে?

পটভূমি: অবশ্যই, আমি কেবল পরীক্ষার নাম মুদ্রণ করতে চাই না। আমি টেস্ট-নির্দিষ্ট ডেটা লোড করতে চাই যা পরীক্ষার মতো একই নামে একটি সংস্থানে সঞ্চিত থাকে। আপনি জানেন, কনফিগারেশন এবং সমস্ত কিছুর উপর কনভেনশন


উপরের কোডটি আপনাকে কীভাবে 4 ইউনাইটে দেয়?
দ্য টিকটিকি

5
JUnit 3 টি টেস্ট কেস বাড়ায় যেখানে getName () সংজ্ঞায়িত করা হয়। JUnit 4 টি পরীক্ষা বেস ক্লাসটি বাড়ায় না, তাই কোনও getName () পদ্ধতি নেই।
ডেভ রে

আমার একই ধরণের সমস্যা আছে যেখানে আমি পরীক্ষার নামটি <b> সেট </ b> করতে চাইছি যেহেতু আমি প্যারামিট্রাইজড রানার ব্যবহার করছি যা আমাকে কেবল পরীক্ষিত কেস দেয়।
ভোলকার স্টলজ

টেস্ট বা টেস্টওয়াটার ব্যবহার করে সুদৃ just় সমাধান ... শুধু ভাবছেন (জোরে জোরে) এর কি কখনও দরকার আছে কিনা? গ্রেডল প্রদত্ত টাইমিং আউটপুট চার্টগুলি দেখে কোনও পরীক্ষা ধীরে ধীরে চলছে কিনা তা আপনি আবিষ্কার করতে পারেন। কোন টেস্টে ক্রমটি ক্রিয়াকলাপ পরিচালনা করে তা আপনার জানা উচিত নয় ...?
মাইকে রডেন্ট

উত্তর:


378

JUnit 4.7 টেস্টনাম-বিধিটি ব্যবহার করে বলে মনে হচ্ছে এই বৈশিষ্ট্যটি যুক্ত করেছে । দেখে মনে হচ্ছে এটি আপনাকে পদ্ধতির নামটি পেয়ে যাবে:

import org.junit.Rule;

public class NameRuleTest {
    @Rule public TestName name = new TestName();

    @Test public void testA() {
        assertEquals("testA", name.getMethodName());
    }

    @Test public void testB() {
        assertEquals("testB", name.getMethodName());
    }
}

4
আরও মনে রাখবেন যে টেস্টনামটি @ পূর্বপূর্বে পাওয়া যায় না :( দেখুন: old.nabble.com/…
জেএম।

41
দৃশ্যত JUnit এর আরও নতুন সংস্করণগুলি এর @Ruleআগে চালিত হয় @Before- আমি JUnit এ নতুন TestNameএবং আমার @Beforeউপর কোনও অসুবিধা ছাড়াই নির্ভর করে ।
মাইটিই


2
আপনি যদি প্যারামিটারাইজড টেস্ট ব্যবহার করছেন "name.getMethodName ()" ফিরে আসবে - টেস্টএ [0], টেস্টএ [1], ইত্যাদি} এইভাবে আমি কিছু ব্যবহার করি: assertTrue (name.getMethodName ()। ম্যাচ ("টেস্টএ (([\ \ ঘ \]) "));
লেগনা

2
@ ডানকোনজোনস প্রস্তাবিত বিকল্পটি "আরও দক্ষ" কেন?
স্টিফান

117

জুনিয়ট ৪.৯.x এবং উচ্চতর

জুনিয়িত ৪.৯-এর পর থেকে, TestWatchmanক্লাসটি ক্লাসের পক্ষে প্রত্যাখ্যান করা হয়েছে TestWatcher, যার প্রার্থনা রয়েছে:

@Rule
public TestRule watcher = new TestWatcher() {
   protected void starting(Description description) {
      System.out.println("Starting test: " + description.getMethodName());
   }
};

দ্রষ্টব্য: ধারণকারী শ্রেণিটি অবশ্যই ঘোষণা করতে হবে public

জুনিট 4.7.x - 4.8.x

নিম্নলিখিত পদ্ধতিটি একটি শ্রেণিতে সমস্ত পরীক্ষার জন্য পদ্ধতির নামগুলি মুদ্রণ করবে:

@Rule
public MethodRule watchman = new TestWatchman() {
   public void starting(FrameworkMethod method) {
      System.out.println("Starting test: " + method.getName());
   }
};

1
@ টাকাকসট এটি অবাক করা আপনি কি দয়া করে এ সম্পর্কে একটি নতুন প্রশ্ন পোস্ট করতে এবং এখানে লিঙ্কটি পিং করতে পারেন?
ডানকান জোন্স

কেন একটি publicক্ষেত্র ব্যবহার ?
রাফি খ্যাচাডৌড়িয়ান


16

5 এবং উচ্চতর JUnit

ইন JUnit 5 আপনি উদ্বুদ্ধ করতে পারেন TestInfoপরীক্ষা পদ্ধতি প্রদানের যা সহজসাধ্য পরীক্ষা মেটা ডেটা। উদাহরণ স্বরূপ:

@Test
@DisplayName("This is my test")
@Tag("It is my tag")
void test1(TestInfo testInfo) {
    assertEquals("This is my test", testInfo.getDisplayName());
    assertTrue(testInfo.getTags().contains("It is my tag"));
}

আরও দেখুন: JUnit 5 ব্যবহারকারী গাইড , TestInfo জাভাদোক


9

পরিবর্তে এটি চেষ্টা করুন:

public class MyTest {
        @Rule
        public TestName testName = new TestName();

        @Rule
        public TestWatcher testWatcher = new TestWatcher() {
            @Override
            protected void starting(final Description description) {
                String methodName = description.getMethodName();
                String className = description.getClassName();
                className = className.substring(className.lastIndexOf('.') + 1);
                System.err.println("Starting JUnit-test: " + className + " " + methodName);
            }
        };

        @Test
        public void testA() {
                assertEquals("testA", testName.getMethodName());
        }

        @Test
        public void testB() {
                assertEquals("testB", testName.getMethodName());
        }
}

আউটপুটটি দেখতে এমন দেখাচ্ছে:

Starting JUnit-test: MyTest testA
Starting JUnit-test: MyTest testB

দ্রষ্টব্য: আপনার পরীক্ষাটি টেস্টকেসের একটি সাবক্লাস হলে এটি কাজ করে না ! পরীক্ষা চলে তবে @ বিধি কোডটি কখনই চালায় না।


3
Godশ্বর উদাহরণ হিসাবে খুব আপনার নোট জন্য আপনাকে মঙ্গল করুন।
ব্যবহারকারী 655419

"এটি কাজ করে না" - পয়েন্টে শসা @ বিধি বিধানগুলি উপেক্ষা করে
বেঞ্জিনিয়ার

8

এসএলএফ 4 জে ব্যবহার করার কথা বিবেচনা করুন (জাভাটির জন্য সিম্পল লগিং ফ্যাসাদ) প্যারামিটারাইজড বার্তা ব্যবহার করে কিছু ঝরঝরে উন্নতি সরবরাহ করে। JUnit 4 বিধি বাস্তবায়নের সাথে এসএলএফ 4 জে যুক্ত আরও কার্যকর পরীক্ষার শ্রেণি লগিং কৌশল সরবরাহ করতে পারে।

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.MethodRule;
import org.junit.rules.TestWatchman;
import org.junit.runners.model.FrameworkMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LoggingTest {

  @Rule public MethodRule watchman = new TestWatchman() {
    public void starting(FrameworkMethod method) {
      logger.info("{} being run...", method.getName());
    }
  };

  final Logger logger =
    LoggerFactory.getLogger(LoggingTest.class);

  @Test
  public void testA() {

  }

  @Test
  public void testB() {

  }
}

6

একটি কনভোল্টেড উপায় হল org.junit.runners.BlockJUnit4ClassRunner সাবক্লাসিং করে নিজের রানার তৈরি করা।

তারপরে আপনি এর মতো কিছু করতে পারেন:

public class NameAwareRunner extends BlockJUnit4ClassRunner {

    public NameAwareRunner(Class<?> aClass) throws InitializationError {
        super(aClass);
    }

    @Override
    protected Statement methodBlock(FrameworkMethod frameworkMethod) {
        System.err.println(frameworkMethod.getName());
        return super.methodBlock(frameworkMethod);
    }
}

তারপরে প্রতিটি পরীক্ষার ক্লাসের জন্য আপনার একটি @ রুনউইথ (নেমআওয়্যারআরওয়ান.ক্র্লাস) টিকা যুক্ত করতে হবে। বিকল্পভাবে, আপনি যদি প্রতিবার এটি মনে রাখতে না চান তবে আপনি এ টীকাকে একটি টেস্ট সুপারক্লাসে রাখতে পারেন। এটি অবশ্যই আপনার রানার নির্বাচন সীমাবদ্ধ করে তবে তা গ্রহণযোগ্য হতে পারে।

এছাড়াও, বর্তমান পরীক্ষার নাম রানার থেকে বেরিয়ে আসতে এবং আপনার কাঠামোর মধ্যে পেতে খানিকটা কুংফু লাগতে পারে তবে এটি অন্তত আপনার নামটি পেয়ে যায়।


ধারণাটি কমপক্ষে, এই ধারণাটি আমার কাছে বরং সহজ বলে মনে হচ্ছে। আমার বক্তব্যটি: আমি এটিকে সংঘাতযুক্ত বলব না।
ব্যবহারকারী 98761

"টেস্ট সুপারক্লাসে ..." - দয়া করে ভয়াবহ উত্তরাধিকার ভিত্তিক নকশা নিদর্শনগুলির আর কোনও নয়। এটি তাই JUnit3!
ওবলিস

3

JUnit 4 এর নিজের নাম (সেটআপ এবং টিয়ারডাউন সহ) সহ নিজের নাম পাওয়ার জন্য কোনও পরীক্ষার মামলার বাইরের কোনও বাক্য নেই।


1
স্ট্যাক পরিদর্শন করা ছাড়া বাক্সের বাইরে নেই এমন কোনও বাকী প্রক্রিয়া আছে কি?
ডেভ রে

4
মামলার নীচে উত্তর দেওয়া হয়নি! অন্য কারও কাছে সঠিক উত্তর অর্পণ করতে পারেন?
টবি

3
String testName = null;
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
for (int i = trace.length - 1; i > 0; --i) {
    StackTraceElement ste = trace[i];
    try {
        Class<?> cls = Class.forName(ste.getClassName());
        Method method = cls.getDeclaredMethod(ste.getMethodName());
        Test annotation = method.getAnnotation(Test.class);
        if (annotation != null) {
            testName = ste.getClassName() + "." + ste.getMethodName();
            break;
        }
    } catch (ClassNotFoundException e) {
    } catch (NoSuchMethodException e) {
    } catch (SecurityException e) {
    }
}

1
আমি যুক্তি দিতে পারি যে তিনি কেবল একটি সমাধান দেখাতে চেয়েছিলেন .. নেতিবাচক ভোট কেন দেখেন না .... @ ডাউনভিটার: কমপক্ষে, কমপক্ষে, দরকারী তথ্য যুক্ত করুন ..
ভিক্টর

1
@ স্কাফম্যান আমাদের সকলের বিকল্প সমাধানের সম্পূর্ণ পরিসীমা দেখতে ভালোবাসি। এটি আমি যা খুঁজছি তার নিকটতম এটি: টেস্টের নামটি সরাসরি টেস্টক্লাসে নয় বরং পরীক্ষার সময় ব্যবহৃত হয় এমন শ্রেণিতে (উদাহরণস্বরূপ লগার উপাদান হিসাবে) the সেখানে, পরীক্ষার-সম্পর্কিত টিকাগুলি আর কাজ করে না।
ড্যানিয়েল অ্যাল্ডার

3

পূর্ববর্তী মন্তব্যের ভিত্তিতে এবং আরও বিবেচনা করে আমি টেস্টওয়ার্ডের একটি এক্সটেনশন তৈরি করেছি যা আপনি এটি দিয়ে আপনার JUnit পরীক্ষা পদ্ধতিতে ব্যবহার করতে পারেন:

public class ImportUtilsTest {
    private static final Logger LOGGER = Logger.getLogger(ImportUtilsTest.class);

    @Rule
    public TestWatcher testWatcher = new JUnitHelper(LOGGER);

    @Test
    public test1(){
    ...
    }
}

পরের পরীক্ষার সহায়ক শ্রেণি:

public class JUnitHelper extends TestWatcher {
private Logger LOGGER;

public JUnitHelper(Logger LOGGER) {
    this.LOGGER = LOGGER;
}

@Override
protected void starting(final Description description) {
    LOGGER.info("STARTED " + description.getMethodName());
}

@Override
protected void succeeded(Description description) {
    LOGGER.info("SUCCESSFUL " + description.getMethodName());
}

@Override
protected void failed(Throwable e, Description description) {
    LOGGER.error("FAILURE " + description.getMethodName());
}
}

উপভোগ করুন!


হাই এটি কী ImportUtilsTest, আমি একটি ত্রুটি পেয়েছি, এটি একটি লগার ক্লাস বলে মনে হচ্ছে, আমার আরও তথ্য আছে? ধন্যবাদ
সিলেহর

1
নামী বর্গটি একটি জুনাইট পরীক্ষার শ্রেণীর উদাহরণ: জনিট হেল্পারের ব্যবহারকারী। আমি ব্যবহারের উদাহরণটি সংশোধন করব।
সিসাবা টেনকেস

আহ এখন আমি বোবা বোধ করছি, এটি এতটাই স্পষ্ট ছিল। অনেক ধন্যবাদ! ;)
সিলেরে

1
@ClassRule
public static TestRule watchman = new TestWatcher() {
    @Override
    protected void starting( final Description description ) {
        String mN = description.getMethodName();
        if ( mN == null ) {
            mN = "setUpBeforeClass..";
        }

        final String s = StringTools.toString( "starting..JUnit-Test: %s.%s", description.getClassName(), mN );
        System.err.println( s );
    }
};

0

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


0

আপনি Slf4jএবং এটি ব্যবহার করে এটি অর্জন করতে পারেনTestWatcher

private static Logger _log = LoggerFactory.getLogger(SampleTest.class.getName());

@Rule
public TestWatcher watchman = new TestWatcher() {
    @Override
    public void starting(final Description method) {
        _log.info("being run..." + method.getMethodName());
    }
};

0

JUnit 5 এ TestInfoJUnit 4 থেকে টেস্টনামের নিয়মের জন্য ড্রপ-ইন প্রতিস্থাপন হিসাবে কাজ করে।

ডকুমেন্টেশন থেকে:

টেস্টইনফো বর্তমান পরীক্ষার বা ধারক সম্পর্কে তথ্য ইনটেক্স করতে ব্যবহার করা হয় @ টেস্ট, @ রিপেনডেস্ট, @ পারমেটারাইজড টেস্ট, @ টেস্টফ্যাক্টরি, @ বিফরএচ, @ আফটারইচ, @ বেফারএল এবং @ আফটারআল পদ্ধতিতে।

বর্তমান সম্পাদিত পরীক্ষার পদ্ধতির নামটি পুনরুদ্ধার করতে আপনার কাছে দুটি বিকল্প রয়েছে: String TestInfo.getDisplayName()এবং Method TestInfo.getTestMethod()

কেবলমাত্র পরীক্ষা পদ্ধতিটির নাম পুনরুদ্ধার করার TestInfo.getDisplayName()জন্য পরীক্ষা পদ্ধতির ডিফল্ট প্রদর্শন নামটি যথেষ্ট নাও হতে পারে methodName(TypeArg1, TypeArg2, ... TypeArg3)
পদ্ধতির নামগুলিতে সদৃশ করা @DisplayName("..")ভাল ধারণা নয়।

বিকল্প হিসাবে আপনি এটি ব্যবহার করতে পারেন TestInfo.getTestMethod()যে কোনও Optional<Method>বস্তু ফেরত দেয় ।
যদি পুনরুদ্ধার পদ্ধতিটি কোনও পরীক্ষার পদ্ধতির অভ্যন্তরে ব্যবহৃত Optionalহয় তবে আপনার মোড়ানো মানটি পরীক্ষা করার দরকার নেই ।

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.Test;

@Test
void doThat(TestInfo testInfo) throws Exception {
    Assertions.assertEquals("doThat(TestInfo)",testInfo.getDisplayName());
    Assertions.assertEquals("doThat",testInfo.getTestMethod().get().getName());
}

0

এক্সটেনশনকন্টেক্সটের মাধ্যমে 5 জুনবিট করুন

সুবিধা:

ExtensionContextওভাররাইড করে আপনার সংযুক্ত ক্রিয়াকলাপগুলি পেতে পারেন afterEach(ExtensionContext context)

public abstract class BaseTest {

    protected WebDriver driver;

    @RegisterExtension
    AfterEachExtension afterEachExtension = new AfterEachExtension();

    @BeforeEach
    public void beforeEach() {
        // Initialise driver
    }

    @AfterEach
    public void afterEach() {
        afterEachExtension.setDriver(driver);
    }

}
public class AfterEachExtension implements AfterEachCallback {

    private WebDriver driver;

    public void setDriver(WebDriver driver) {
        this.driver = driver;
    }

    @Override
    public void afterEach(ExtensionContext context) {
        String testMethodName = context.getTestMethod().orElseThrow().getName();
        // Attach test steps, attach scsreenshots on failure only, etc.
        driver.quit();
    }

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