001/*
002 * Copyright 2002-2018 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.test.annotation;
018
019import java.lang.annotation.Documented;
020import java.lang.annotation.ElementType;
021import java.lang.annotation.Inherited;
022import java.lang.annotation.Retention;
023import java.lang.annotation.RetentionPolicy;
024import java.lang.annotation.Target;
025
026/**
027 * Test annotation to indicate whether a test is enabled or disabled for a
028 * specific testing profile.
029 *
030 * <p>In the context of this annotation, the term <em>profile</em> refers to
031 * a Java system property by default; however, the semantics can be changed
032 * by implementing a custom {@link ProfileValueSource}. If the configured
033 * {@code ProfileValueSource} returns a matching {@link #value} for the
034 * declared {@link #name}, the test will be enabled. Otherwise, the test
035 * will be disabled and effectively <em>ignored</em>.
036 *
037 * <p>{@code @IfProfileValue} can be applied at the class level, the method
038 * level, or both. Class-level usage of {@code @IfProfileValue} takes
039 * precedence over method-level usage for any methods within that class or
040 * its subclasses. Specifically, a test is enabled if it is enabled both at
041 * the class level <em>and</em> at the method level; the absence of
042 * {@code @IfProfileValue} means the test is implicitly enabled. This is
043 * analogous to the semantics of JUnit's {@link org.junit.Ignore @Ignore}
044 * annotation, except that the presence of {@code @Ignore} always disables
045 * a test.
046 *
047 * <h3>Example</h3>
048 * When using {@link SystemProfileValueSource} as the {@code ProfileValueSource}
049 * implementation (which is configured by default), you can configure a test
050 * method to run only on Java VMs from Oracle as follows:
051 *
052 * <pre class="code">
053 * &#064;IfProfileValue(name = &quot;java.vendor&quot;, value = &quot;Oracle Corporation&quot;)
054 * public void testSomething() {
055 *     // ...
056 * }</pre>
057 *
058 * <h3>'OR' Semantics</h3>
059 * <p>You can alternatively configure {@code @IfProfileValue} with <em>OR</em>
060 * semantics for multiple {@link #values}. The following test will be enabled
061 * if a {@code ProfileValueSource} has been appropriately configured for the
062 * {@code "test-groups"} profile with a value of either {@code unit-tests}
063 * <em>or</em> {@code integration-tests}. This functionality is similar to
064 * TestNG's support for test <em>groups</em> and JUnit's experimental support
065 * for test <em>categories</em>.
066 *
067 * <pre class="code">
068 * &#064;IfProfileValue(name = &quot;test-groups&quot;, values = { &quot;unit-tests&quot;, &quot;integration-tests&quot; })
069 * public void testWhichRunsForUnitOrIntegrationTestGroups() {
070 *     // ...
071 * }</pre>
072 *
073 * <h3>{@code @IfProfileValue} vs. {@code @Profile}</h3>
074 * <p>Although the {@code @IfProfileValue} and
075 * {@link org.springframework.context.annotation.Profile @Profile} annotations
076 * both involve <em>profiles</em>, they are not directly related. {@code @Profile}
077 * involves bean definition profiles configured in the
078 * {@link org.springframework.core.env.Environment Environment}; whereas,
079 * {@code @IfProfileValue} is used to enable or disable tests.
080 *
081 * <h3>Meta-annotation Support</h3>
082 * <p>As of Spring Framework 4.0, this annotation may be used as a
083 * <em>meta-annotation</em> to create custom <em>composed annotations</em>.
084 *
085 * @author Rod Johnson
086 * @author Sam Brannen
087 * @since 2.0
088 * @see ProfileValueSource
089 * @see SystemProfileValueSource
090 * @see ProfileValueSourceConfiguration
091 * @see ProfileValueUtils
092 * @see org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests
093 * @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
094 * @see org.springframework.test.context.junit4.statements.ProfileValueChecker
095 * @see org.springframework.context.annotation.Profile
096 * @see org.springframework.test.context.ActiveProfiles
097 */
098@Target({ElementType.TYPE, ElementType.METHOD})
099@Retention(RetentionPolicy.RUNTIME)
100@Documented
101@Inherited
102public @interface IfProfileValue {
103
104        /**
105         * The {@code name} of the <em>profile value</em> against which to test.
106         */
107        String name();
108
109        /**
110         * A single, permissible {@code value} of the <em>profile value</em>
111         * for the given {@link #name}.
112         * <p>Note: Assigning values to both {@code #value} and {@link #values}
113         * will lead to a configuration conflict.
114         */
115        String value() default "";
116
117        /**
118         * A list of all permissible {@code values} of the <em>profile value</em>
119         * for the given {@link #name}.
120         * <p>Note: Assigning values to both {@link #value} and {@code #values}
121         * will lead to a configuration conflict.
122         */
123        String[] values() default {};
124
125}