উত্তর:
এই বৈশিষ্ট্যটি এটিকে JUnit 4.11 এ পরিণত করেছে ।
প্যারামিটারাইজড পরীক্ষার নাম পরিবর্তন করতে, আপনি বলেছেন:
@Parameters(name="namestring")
namestring
একটি স্ট্রিং, যা নিম্নলিখিত বিশেষ স্থানধারক থাকতে পারে:
{index}
- এই আর্গুমেন্টের সেট। ডিফল্ট namestring
হয় {index}
।{0}
- পরীক্ষার এই অনুরোধ থেকে প্রথম প্যারামিটার মান।{1}
- দ্বিতীয় প্যারামিটার মানপরীক্ষার চূড়ান্ত নামটি পরীক্ষার পদ্ধতির নাম হবে namestring
, নীচে দেখানো অনুসারে বন্ধনীগুলি অনুসরণ করবে ।
উদাহরণস্বরূপ (টীকাটির জন্য ইউনিট পরীক্ষা থেকে অভিযোজিত Parameterized
):
@RunWith(Parameterized.class)
static public class FibonacciTest {
@Parameters( name = "{index}: fib({0})={1}" )
public static Iterable<Object[]> data() {
return Arrays.asList(new Object[][] { { 0, 0 }, { 1, 1 }, { 2, 1 },
{ 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 } });
}
private final int fInput;
private final int fExpected;
public FibonacciTest(int input, int expected) {
fInput= input;
fExpected= expected;
}
@Test
public void testFib() {
assertEquals(fExpected, fib(fInput));
}
private int fib(int x) {
// TODO: actually calculate Fibonacci numbers
return 0;
}
}
testFib[1: fib(1)=1]
এবং মত নাম দেবে testFib[4: fib(4)=3]
। ( testFib
নামের অংশটি হ'ল পদ্ধতিটির নাম @Test
)।
{0}
এবং {1}
অ্যারে হয়? ইউনাইটের আদর্শভাবে ফোন করা উচিত Arrays.toString({0})
, নয় {0}.toString()
। উদাহরণস্বরূপ, আমার data()
পদ্ধতিটি ফিরে আসে Arrays.asList(new Object[][] {{ new int[] { 1, 3, 2 }, new int[] { 1, 2, 3 } }});
।
JUnit 4.5 এর দিকে তাকিয়ে, এর রানার স্পষ্টভাবে সেটিকে সমর্থন করে না, কারণ এই যুক্তিটি প্যারামিটারাইজড শ্রেণীর ভিতরে একটি প্রাইভেট ক্লাসের মধ্যে সমাধিস্থ করা হয়েছে। আপনি JUnit প্যারামিটারাইজড রানারটি ব্যবহার করতে পারবেন না এবং পরিবর্তে নিজের তৈরি করতে পারেন যা নামের ধারণাটি বুঝতে পারে (যার ফলে আপনি কীভাবে একটি নাম সেট করতে পারেন এই প্রশ্নের দিকে নিয়ে যায় ...)।
জুনিত দৃষ্টিকোণ থেকে, এটি দুর্দান্ত হবে যদি পরিবর্তে (বা এটি ছাড়াও) কেবলমাত্র একটি ইনক্রিমেন্ট পাস করার পরিবর্তে তারা কমা বিস্মৃত আর্গুমেন্টগুলি পাস করে। টেস্টএনজি এটি করে। যদি বৈশিষ্ট্যটি আপনার কাছে গুরুত্বপূর্ণ হয় তবে আপনি www.junit.org এ রেফারেন্সযুক্ত ইয়াহু মেইলিং লিস্টে মন্তব্য করতে পারেন।
জুনিট ৪.৩.১ ব্যবহার করার সময় আমি একই সমস্যাটি পেয়েছি। আমি একটি নতুন ক্লাস প্রয়োগ করেছি যা লেবেলপ্রেমেটারাইজড নামে প্যারামিটারাইজড প্রসারিত করে। এটি JUnit 4.3.1, 4.4 এবং 4.5 ব্যবহার করে পরীক্ষা করা হয়েছে। এটি @ প্যারামিটার পদ্ধতি থেকে প্রতিটি প্যারামিটার অ্যারের প্রথম যুক্তির স্ট্রিং উপস্থাপনা ব্যবহার করে বিবরণ দৃষ্টান্ত পুনর্গঠন করে। আপনি এর জন্য কোডটি এখানে দেখতে পারেন:
http://code.google.com/p/migen/source/browse/trunk/java/src/.../LabelledParameterized.java?r=3789
এবং এর ব্যবহারের উদাহরণ এখানে:
http://code.google.com/p/migen/source/browse/trunk/java/src/.../ServerBuilderTest.java?r=3789
পরীক্ষার বিবরণটি Eclipse এ সুন্দরভাবে ফর্ম্যাট করে যা আমি চেয়েছিলাম যেহেতু এটি ব্যর্থ পরীক্ষাগুলি খুঁজে পাওয়া অনেক সহজ করে দেয়! আমি সম্ভবত পরবর্তী কয়েক দিন / সপ্তাহগুলিতে ক্লাসগুলি আরও পরিমার্জন এবং নথিভুক্ত করব। ঝরা '?' ইউআরএল এর অংশ যদি আপনি রক্তপাত প্রান্ত চান। :-)
এটি ব্যবহার করার জন্য আপনাকে যা করতে হবে তা হ'ল ক্লাসটি (জিপিএল ভি 3) অনুলিপি করে আপনার @ প্যারামিটার তালিকার প্রথম উপাদানটিকে ধরে রেখে @ রুনউইথ (প্যারামিটারাইজড.ক্লাস) @ রুনউইথ (লেবেলপ্রেমেটারাইজড.ক্লাস) এ পরিবর্তন করতে হবে sens
আমি জানিনা জুনিতের পরবর্তী কোনও রিলিজ এই ইস্যুটিকে সম্বোধন করে কিনা তবে তারা তা করে থাকলেও আমি জুনিতকে আপডেট করতে পারছি না কারণ আমার সমস্ত সহ-বিকাশকারীকেও আপডেট করতে হবে এবং রি-টুলিংয়ের চেয়ে আমাদের উচ্চ অগ্রাধিকার রয়েছে। সুতরাং ক্লাসে কাজটি JUnit এর একাধিক সংস্করণ দ্বারা সংকলনীয় হতে পারে।
দ্রষ্টব্য: কিছু প্রতিবিম্ব জিগ্রি-পোকারি রয়েছে যাতে এটি উপরে তালিকাবদ্ধ হিসাবে বিভিন্ন JUnit সংস্করণ জুড়ে চলে। বিশেষত JUnit 4.3.1 এর সংস্করণটি এখানে এবং জুনিয়ট 4.4 এবং 4.5 এর জন্য পাওয়া যাবে ।
execute[0], execute[1] ... execute[n]
উত্পন্ন পরীক্ষার রিপোর্টে পরীক্ষার রিপোর্টগুলির নাম দেওয়া হয়।
সঙ্গে Parameterized
মডেল হিসেবে, আমি আমার নিজস্ব পরীক্ষা রানার / স্যুট লিখেছে - মাত্র আধা ঘন্টার নেন। এটি ড্যারেন্পের থেকে কিছুটা আলাদা LabelledParameterized
যে এটি আপনাকে প্রথম প্যারামিটারের উপর নির্ভর না করে স্পষ্টভাবে একটি নাম নির্দিষ্ট করতে দেয় toString()
।
এটি অ্যারে ব্যবহার করে না কারণ আমি অ্যারেগুলি ঘৃণা করি। :)
public class PolySuite extends Suite {
// //////////////////////////////
// Public helper interfaces
/**
* Annotation for a method which returns a {@link Configuration}
* to be injected into the test class constructor
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public static @interface Config {
}
public static interface Configuration {
int size();
Object getTestValue(int index);
String getTestName(int index);
}
// //////////////////////////////
// Fields
private final List<Runner> runners;
// //////////////////////////////
// Constructor
/**
* Only called reflectively. Do not use programmatically.
* @param c the test class
* @throws Throwable if something bad happens
*/
public PolySuite(Class<?> c) throws Throwable {
super(c, Collections.<Runner>emptyList());
TestClass testClass = getTestClass();
Class<?> jTestClass = testClass.getJavaClass();
Configuration configuration = getConfiguration(testClass);
List<Runner> runners = new ArrayList<Runner>();
for (int i = 0, size = configuration.size(); i < size; i++) {
SingleRunner runner = new SingleRunner(jTestClass, configuration.getTestValue(i), configuration.getTestName(i));
runners.add(runner);
}
this.runners = runners;
}
// //////////////////////////////
// Overrides
@Override
protected List<Runner> getChildren() {
return runners;
}
// //////////////////////////////
// Private
private Configuration getConfiguration(TestClass testClass) throws Throwable {
return (Configuration) getConfigMethod(testClass).invokeExplosively(null);
}
private FrameworkMethod getConfigMethod(TestClass testClass) {
List<FrameworkMethod> methods = testClass.getAnnotatedMethods(Config.class);
if (methods.isEmpty()) {
throw new IllegalStateException("@" + Config.class.getSimpleName() + " method not found");
}
if (methods.size() > 1) {
throw new IllegalStateException("Too many @" + Config.class.getSimpleName() + " methods");
}
FrameworkMethod method = methods.get(0);
int modifiers = method.getMethod().getModifiers();
if (!(Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new IllegalStateException("@" + Config.class.getSimpleName() + " method \"" + method.getName() + "\" must be public static");
}
return method;
}
// //////////////////////////////
// Helper classes
private static class SingleRunner extends BlockJUnit4ClassRunner {
private final Object testVal;
private final String testName;
SingleRunner(Class<?> testClass, Object testVal, String testName) throws InitializationError {
super(testClass);
this.testVal = testVal;
this.testName = testName;
}
@Override
protected Object createTest() throws Exception {
return getTestClass().getOnlyConstructor().newInstance(testVal);
}
@Override
protected String getName() {
return testName;
}
@Override
protected String testName(FrameworkMethod method) {
return testName + ": " + method.getName();
}
@Override
protected void validateConstructor(List<Throwable> errors) {
validateOnlyOneConstructor(errors);
}
@Override
protected Statement classBlock(RunNotifier notifier) {
return childrenInvoker(notifier);
}
}
}
এবং একটি উদাহরণ:
@RunWith(PolySuite.class)
public class PolySuiteExample {
// //////////////////////////////
// Fixture
@Config
public static Configuration getConfig() {
return new Configuration() {
@Override
public int size() {
return 10;
}
@Override
public Integer getTestValue(int index) {
return index * 2;
}
@Override
public String getTestName(int index) {
return "test" + index;
}
};
}
// //////////////////////////////
// Fields
private final int testVal;
// //////////////////////////////
// Constructor
public PolySuiteExample(int testVal) {
this.testVal = testVal;
}
// //////////////////////////////
// Test
@Ignore
@Test
public void odd() {
assertFalse(testVal % 2 == 0);
}
@Test
public void even() {
assertTrue(testVal % 2 == 0);
}
}
জুনিট ৪.৮.২ থেকে আপনি প্যারামিটারাইজড ক্লাসটি অনুলিপি করে নিজের মাইপ্যারমেটারাইজড ক্লাস তৈরি করতে পারেন। টেস্টক্লাসরুনারফোরপ্যারামিটারগুলিতে getName () এবং testName () পদ্ধতি পরিবর্তন করুন।
আপনি JUnitParams চেষ্টা করতেও পারেন: http://code.google.com/p/junitparams/
আপনি একটি পদ্ধতি তৈরি করতে পারেন
@Test
public void name() {
Assert.assertEquals("", inboundFileName);
}
যদিও আমি এটি সমস্ত সময় ব্যবহার করব না তবে 143 নম্বরটি কোনটি ঠিক তা নির্ধারণ করা কার্যকর হবে।
আমি দৃsert় আমন্ত্রণ এবং বন্ধুদের জন্য স্থিতিশীল আমদানির বিস্তৃত ব্যবহার করি, তাই আমার পক্ষে দৃ rede়তার সাথে পুনরায় সংজ্ঞা দেওয়া সহজ:
private <T> void assertThat(final T actual, final Matcher<T> expected) {
Assert.assertThat(editThisToDisplaySomethingForYourDatum, actual, expected);
}
উদাহরণস্বরূপ, আপনি আপনার পরীক্ষার শ্রেণিতে একটি "নাম" ক্ষেত্র যুক্ত করতে পারেন, নির্মাণকারীতে আরম্ভ করেছিলেন এবং পরীক্ষার ব্যর্থতায় এটি প্রদর্শন করতে পারেন। প্রতিটি পরীক্ষার জন্য আপনার প্যারামিটার অ্যারের প্রথম উপাদান হিসাবে এটি পাস করুন। এটি ডেটা লেবেল করতে সহায়তা করে:
public ExampleTest(final String testLabel, final int one, final int two) {
this.testLabel = testLabel;
// ...
}
@Parameters
public static Collection<Object[]> data() {
return asList(new Object[][]{
{"first test", 3, 4},
{"second test", 5, 6}
});
}
এর কোনওটিই আমার পক্ষে কাজ করছে না, তাই আমি প্যারামিটারাইজড এবং পরিবর্তিত এটির জন্য নতুন পরীক্ষার রানার তৈরির উত্স পেয়েছি। আইটি ওয়ার্কস ব্যতীত আমাকে বেশি পরিবর্তন করতে হবে না !!!
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.junit.Assert;
import org.junit.internal.runners.ClassRoadie;
import org.junit.internal.runners.CompositeRunner;
import org.junit.internal.runners.InitializationError;
import org.junit.internal.runners.JUnit4ClassRunner;
import org.junit.internal.runners.MethodValidator;
import org.junit.internal.runners.TestClass;
import org.junit.runner.notification.RunNotifier;
public class LabelledParameterized extends CompositeRunner {
static class TestClassRunnerForParameters extends JUnit4ClassRunner {
private final Object[] fParameters;
private final String fParameterFirstValue;
private final Constructor<?> fConstructor;
TestClassRunnerForParameters(TestClass testClass, Object[] parameters, int i) throws InitializationError {
super(testClass.getJavaClass()); // todo
fParameters = parameters;
if (parameters != null) {
fParameterFirstValue = Arrays.asList(parameters).toString();
} else {
fParameterFirstValue = String.valueOf(i);
}
fConstructor = getOnlyConstructor();
}
@Override
protected Object createTest() throws Exception {
return fConstructor.newInstance(fParameters);
}
@Override
protected String getName() {
return String.format("%s", fParameterFirstValue);
}
@Override
protected String testName(final Method method) {
return String.format("%s%s", method.getName(), fParameterFirstValue);
}
private Constructor<?> getOnlyConstructor() {
Constructor<?>[] constructors = getTestClass().getJavaClass().getConstructors();
Assert.assertEquals(1, constructors.length);
return constructors[0];
}
@Override
protected void validate() throws InitializationError {
// do nothing: validated before.
}
@Override
public void run(RunNotifier notifier) {
runMethods(notifier);
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public static @interface Parameters {
}
private final TestClass fTestClass;
public LabelledParameterized(Class<?> klass) throws Exception {
super(klass.getName());
fTestClass = new TestClass(klass);
MethodValidator methodValidator = new MethodValidator(fTestClass);
methodValidator.validateStaticMethods();
methodValidator.validateInstanceMethods();
methodValidator.assertValid();
int i = 0;
for (final Object each : getParametersList()) {
if (each instanceof Object[])
add(new TestClassRunnerForParameters(fTestClass, (Object[]) each, i++));
else
throw new Exception(String.format("%s.%s() must return a Collection of arrays.", fTestClass.getName(), getParametersMethod().getName()));
}
}
@Override
public void run(final RunNotifier notifier) {
new ClassRoadie(notifier, fTestClass, getDescription(), new Runnable() {
public void run() {
runChildren(notifier);
}
}).runProtected();
}
private Collection<?> getParametersList() throws IllegalAccessException, InvocationTargetException, Exception {
return (Collection<?>) getParametersMethod().invoke(null);
}
private Method getParametersMethod() throws Exception {
List<Method> methods = fTestClass.getAnnotatedMethods(Parameters.class);
for (Method each : methods) {
int modifiers = each.getModifiers();
if (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))
return each;
}
throw new Exception("No public static parameters method on class " + getName());
}
public static Collection<Object[]> eachOne(Object... params) {
List<Object[]> results = new ArrayList<Object[]>();
for (Object param : params)
results.add(new Object[] { param });
return results;
}
}
একটি কার্যপ্রণালী হ'ল পরামিতিগুলির সমস্ত তথ্য সম্বলিত একটি কাস্টম বার্তা সহ সমস্ত থ্রোবেলগুলিকে একটি নতুন থ্রোয়েবলে ধরা এবং বাসা বাঁধতে হবে। বার্তা স্ট্যাক ট্রেস উপস্থিত হবে। এটি যখনই পরীক্ষার সমস্ত দাবি, ত্রুটি এবং ব্যতিক্রমগুলির জন্য ব্যর্থ হয় কারণ এগুলি সমস্ত থ্রোয়েবলের সাবক্লাস।
আমার কোডটি এর মতো দেখাচ্ছে:
@RunWith(Parameterized.class)
public class ParameterizedTest {
int parameter;
public ParameterizedTest(int parameter) {
super();
this.parameter = parameter;
}
@Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] { {1}, {2} });
}
@Test
public void test() throws Throwable {
try {
assertTrue(parameter%2==0);
}
catch(Throwable thrown) {
throw new Throwable("parameter="+parameter, thrown);
}
}
}
ব্যর্থ পরীক্ষার স্ট্যাক ট্রেস হ'ল:
java.lang.Throwable: parameter=1
at sample.ParameterizedTest.test(ParameterizedTest.java:34)
Caused by: java.lang.AssertionError
at org.junit.Assert.fail(Assert.java:92)
at org.junit.Assert.assertTrue(Assert.java:43)
at org.junit.Assert.assertTrue(Assert.java:54)
at sample.ParameterizedTest.test(ParameterizedTest.java:31)
... 31 more
ডিএসএফ হিসাবে উল্লিখিত হিসাবে জুনিতপ্যারামগুলি পরীক্ষা করে দেখুন, এইচটিএমএল প্রতিবেদনে প্যারামিটারাইজড টেস্ট পদ্ধতির বিবরণ তৈরি করতে পিপড়া ব্যবহার করে কাজ করে।
এটি লেবেলপ্যারামিটারাইজড চেষ্টা করার পরে এবং এটি সনাক্ত করা হয়েছিল যে এটি গ্রহণের সাথে কাজ করে যদিও এটি এইচটিএমএল প্রতিবেদনের সাথে সম্পর্কিত, পিপড়া দিয়ে কাজ করে না।
চিয়ার্স,
যেহেতু প্যারামিটার অ্যাক্সেস করা হয়েছে (উদাহরণস্বরূপ "{0}"
সর্বদা toString()
উপস্থাপনাটি ফেরত দেয় , তাই toString()
প্রতিটি ক্ষেত্রে বেনামে বাস্তবায়ন করা এবং ওভাররাইড করা এক কাজ হতে পারে example উদাহরণস্বরূপ:
public static Iterable<? extends Object> data() {
return Arrays.asList(
new MyObject(myParams...) {public String toString(){return "my custom test name";}},
new MyObject(myParams...) {public String toString(){return "my other custom test name";}},
//etc...
);
}