Impact of. Net attribute on unit test [1]

Source: Internet
Author: User

Impact of. Net attribute on unit test

 

Note:
I read Shanyou's "using unit test tool nunit In the. NET environment", which is a good article about Attribute Analysis in IEEE software magazine. After the adaptation, I posted it for your reference.
Property and attribute are generally translated into "attributes". To avoid confusion, attribute is not translated here.

 

Microsoft introduced attribute in the. NET Framework, a method that attaches "declarative information" to the runtime entity, also known as metadata. Objects that can be appended with attribute include: Class, method, property, class variable, etc. In. net, you can also attach attributes to assembly. Different types of attributes describe different information about assembly. For example, the identity class attribute is used to describe the recognition features (names, versions, etc.) of the Assembly. The information class attribute is used to provide more product and company information, and the declaration class attribute is used to describe the configuration information, the strong name attribute is used to describe whether the Assembly uses a signature encrypted with a public key. Applications can read this information at runtime and control their interaction with services such as serialization and security.

. Net attribute and Java mark interface (Marker Interface)

Marker interface is a common design technique in Java. The so-called Mark interface is an interface that does not contain any method or field. It has only one purpose, that is, it is convenient for Java Virtual Machine (JVM) to identify whether a class has a specific attribute. For example:
Public interface serializable {}
If the classes we write require serialization, we must implement this interface:
Public class serializableclass implements serializable
As class developers, we sometimes need to control some serialization-related behaviors. However, in Java, serializable represents the serialization contract interface, but it is not explicitly associated with these actions. When the program requests the JVM to serialize a class at runtime, the JVM will check whether the class implements the serializable interface, it also checks whether the class is defined but does not directly declare methods related to serialization interfaces, such as readresolve, readobject, or writeobject. JVM uses naming conventions and method prototypes to locate these methods through reflection and call them once they are found. However, the serializable interface does not explicitly specify these methods. The serialization class may implement these methods in the simplest form when implementing this interface, which is completely unnecessary. If the method is not explicitly specified in the interface, the prototype of these methods may be incorrectly specified elsewhere. It can be seen that such a processing mechanism of Java is prone to errors. Worse, the check during compilation cannot identify it as an error.
. Net's solution to this problem is an explicit statement ("if you have a pleasure, shout "? ^_^ ). In the simplest example, if a programmer needs to use the serialization function provided by the system to serialize an object, the class attribute serializable can be used to mark the class and declare that the class has the serialization function provided by the system. For example:
[Serializable ()]
Public class myclass {}
Only marking a class serializable does not do anything. If the programmer needs to fully control the serialization process, an iserializable interface must be implemented to specify the method used to control the serialization process. For example:
[Serializable ()]
Public class myclass: iserializable
{
Public myclass (
Serializationinfo info,
Streamingcontext context)
{
//...
}
Public void getobjectdata (
Serializationinfo info,
Streamingcontext context)
{
//...
}
}
During runtime, if a program requests the CLR (Common Language Runtime Library) to serialize a class, the CLR will check whether the class is marked as an attribute with serializable. We can see that the way Java and. Net handle this issue is quite similar. However,. Net's use of attribute is more straightforward, at the cost of introducing a new language structure (language construct ). Java reuse an existing language structure-interface. Through the design technique called "tag interface", it achieves the same feature of attribute and expresses the information that attribute can express. Stroustrup mentioned in "design and evolution of C ++ language" that, in the C/C ++ community, there is a tendency to reuse the existing language structure through some design skills rather than introducing new language structures. The introduction of each new keyword is quite costly. This is actually the different design concepts and guiding philosophy of the programming language. It is necessary to pursue a compact and clean environment in the programming language, so it is necessary to express certain design skills that require a high level of definition, and programming languages at the expense of huge complexity, so that the common syntax has its own ready-made language structure to express but difficult to learn and use, bloated to seek an appropriate balance.

Stylistic naming patterns)

Java usually uses naming rules to identify a specific method. The program uses reflection during running, and a method can be located through the method name. Once found, the program can call and execute it. For example, in the open-source unit testing framework JUnit, when a programmer defines a test method, the method name must start with test. The program that executes the test first verifies that this class inherits from testcase, and then uses reflection to find all methods starting with test. For example:
Public class myclass extends testcase
{
Public void testsuccess ()
{/*...*/}
}
If a programmer needs to verify whether the code throws an exception, the following common design Convention can be used in JUnit:
Public class myclass extends testcase
{
Public void testmyexception ()
{
Try {
/* Code that throws exception */
Fail ("code shocould have thrown myexception ");
}
Catch (myexception E)
{/* Expected exception-success */}
}
}
This design convention is not intuitive, and such code must be added to every test case that expects exceptions to occur, which is repetitive and cumbersome. This is a common situation. We may allow the JUnit framework to provide direct support for this. However, relying on naming conventions to identify a method can lead to worse conditions, as shown in the following example:
Public class myclass extends testcase
{
Public void testsuccess_expectexception_myexception ()
{/*...*/}
}
In the above example, we use the naming convention to explain that this is a test method, and we expect that the exception of myexception will be thrown after the method is executed. It can be seen that it is difficult for the method name to pass so much extra information that it is a bit "unbearable. Although the above example is a bit extreme, it does reveal that the application of naming conventions has great limitations, and the name itself cannot carry too much information. In fact, JUnit does not use this method to check boundary conditions. There are other methods in Java (such as javadoc tag) that can play the role of attaching information, but they do not appear at runtime, and they usually require code preprocessing to identify and process these tags.

In. net, the formatting naming mode is completely unnecessary. In addition to the attribute provided by the. NET Framework, programmers can also create their own custom attribute. Custom Attributes are defined and used exactly the same as those provided by the system. These attributes are not just names. They are class instances and can contain additional data. Let's take a look at nunit, a variant of JUnit on the. NET platform (derivative) that supports unit testing in various languages on the. NET platform. Nunit uses attribute at the class and method levels. class attribute is called testfixture, and method attribute is called test. In the following example, the test execution program finds the method where attribute is test in the class with attribute testfixture. This overall solution is in one breath and has no sense of breaking.
[Testfixture]
Public class myclass
{
[Test]
Public void success ()
{/*...*/}
}
This solution is more scalable because there can be more than one attribute for a method, and the attribute can also have additional data. For example, nunit also has a method attribute, indicating that an exception will be thrown after the method is executed. This not only makes the method name not limited to the running environment, but also is more relevant to the content to be tested. For example:
[Testfixture]
Public class myclass
{
[Test]
[Expectedexception (typeof (myexception)]
Public void success ()

 

{/* Wocould throw my exception */}
}

Attribute in. Net is a more elegant and consistent method for attaching declarative information to the runtime object. Because the runtime entity interacts with the supported services through declarative information, these services and attributes (that is, the representation of declarative information) do not have to be fixed. Custom attribute ,. NET provides a standard mechanism to expand the built-in metadata of the system, so that programmers can develop applications that can interact with services not supported or not yet defined by CLR. In fact, nunit2.0 is written using custom attribute, which provides the flexibility we mentioned. And. compared with the attribute solution of net, common methods for attaching declarative information in Java, such as marking interfaces, formatting naming modes, and javadoc tags, lack of consistency and error-prone, it is too simple for today's increasingly complex applications. The Java Community has been aware of this problem, and the jsr-175 sets a feature similar to. Net's existing attribute for the Java platform.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.