Статьи

Поддержка весеннего тестирования с TestNG

TestNG — это тестовая среда, разработанная для охвата всех категорий тестов: модульные, функциональные, сквозные, интеграционные (и т. Д.). Он включает в себя множество функций, таких как гибкая конфигурация тестирования, поддержка тестирования на основе данных (с @DataProvider), мощная модель выполнения (больше не TestSuite) (и т. Д.)

Поддержка тестирования Spring включает в себя очень полезные и важные функции для модульного и интеграционного тестирования приложений на основе Spring. Пакет org.springframework.test.context.testng предоставляет классы поддержки для тестовых случаев на основе TestNG. В этой статье показано, как тестировать компоненты уровня Spring Service с помощью интеграции Spring и TestNG. Также в следующей статье будет показано, как тестировать компоненты слоя Spring Data Access, используя ту же интеграцию.

Используемые технологии:

JDK 1.6.0_31
Весна 3.1.1
TestNG 6.4
Maven 3.0.2

ШАГ 1: СОЗДАТЬ MAVEN ПРОЕКТ

Maven проект создается следующим образом. (Его можно создать с помощью Maven или IDE Plug-in).

ШАГ 2: БИБЛИОТЕКИ

Spring-зависимости добавляются в pom.xml Maven.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<properties>
 <spring.version>3.1.1.RELEASE</spring.version>
</properties>
 
<dependencies>
       <!-- Spring 3 dependencies -->
       <dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>${spring.version}</version>
 </dependency>
 
 <dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>${spring.version}</version>
 </dependency>
 
 <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-test</artifactId>
           <version>${spring.version}</version>
       </dependency>
 
       <!-- TestNG dependency -->
       <dependency>
  <groupId>org.testng</groupId>
  <artifactId>testng</artifactId>
  <version>6.4</version>
 </dependency>
 
       <!-- Log4j dependency -->
 <dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.16</version>
 </dependency>
 
</dependencies>

ШАГ 3: СОЗДАЙТЕ ПОЛЬЗОВАТЕЛЬСКИЙ КЛАСС

Новый класс пользователя создан.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package com.otv.user;
 
/**
 * User Bean
 *
 * @author  onlinetechvision.com
 * @since   19 May 2012
 * @version 1.0.0
 *
 */
public class User {
 
 private String id;
 private String name;
 private String surname;
 
 /**
  * Gets User Id
  *
  * @return String id
  */
 public String getId() {
  return id;
 }
 
 /**
  * Sets User Id
  *
  * @param String id
  */
 public void setId(String id) {
  this.id = id;
 }
 
 /**
  * Gets User Name
  *
  * @return String name
  */
 public String getName() {
  return name;
 }
 
 /**
  * Sets User Name
  *
  * @param String name
  */
 public void setName(String name) {
  this.name = name;
 }
 
 /**
  * Gets User Surname
  *
  * @return String Surname
  */
 public String getSurname() {
  return surname;
 }
 
 /**
  * Sets User Surname
  *
  * @param String surname
  */
 public void setSurname(String surname) {
  this.surname = surname;
 }
 
 @Override
 public String toString() {
  StringBuilder strBuilder = new StringBuilder();
  strBuilder.append("Id : ").append(getId());
  strBuilder.append(", Name : ").append(getName());
  strBuilder.append(", Surname : ").append(getSurname());
  return strBuilder.toString();
 }
 
 @Override
 public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result + ((id == null) ? 0 : id.hashCode());
  result = prime * result + ((name == null) ? 0 : name.hashCode());
  result = prime * result + ((surname == null) ? 0 : surname.hashCode());
  return result;
 }
 
 @Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (getClass() != obj.getClass())
   return false;
  User other = (User) obj;
  if (id == null) {
   if (other.id != null)
    return false;
  } else if (!id.equals(other.id))
   return false;
  if (name == null) {
   if (other.name != null)
    return false;
  } else if (!name.equals(other.name))
   return false;
  if (surname == null) {
   if (other.surname != null)
    return false;
  } else if (!surname.equals(other.surname))
   return false;
  return true;
 }
}

ШАГ 4: СОЗДАЙТЕ КЛАСС NonExistentUserException

Класс NonExistentUserException создан.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
package com.otv.common.exceptions;
 
/**
 * Non Existent User Exception
 *
 * @author  onlinetechvision.com
 * @since   19 May 2012
 * @version 1.0.0
 *
 */
public class NonExistentUserException extends Exception {
 
 private static final long serialVersionUID = 1L;
 
 public NonExistentUserException(String message) {
  super(message);
 }
}

ШАГ 5: СОЗДАЙТЕ ИНТЕРФЕЙС ICacheService

Интерфейс ICacheService, представляющий интерфейс службы кэширования, создан.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.otv.cache.service;
 
import java.util.concurrent.ConcurrentHashMap;
 
import com.otv.user.User;
 
/**
 * Cache Service Interface
 *
 * @author  onlinetechvision.com
 * @since   19 May 2012
 * @version 1.0.0
 *
 */
public interface ICacheService {
 
   /**
  * Gets User Map
  *
  * @return ConcurrentHashMap User Map
  */
 ConcurrentHashMap<String, User> getUserMap();
 
}

ШАГ 6: СОЗДАЙТЕ CacheService CLASS

Класс CacheService создается путем реализации интерфейса ICacheService. Предоставляет доступ к удаленному кешу…

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.otv.cache.service;
 
import java.util.concurrent.ConcurrentHashMap;
 
import com.otv.user.User;
 
/**
 * Cache Service Implementation
 *
 * @author  onlinetechvision.com
 * @since   19 May 2012
 * @version 1.0.0
 *
 */
public class CacheService implements ICacheService {
 
 //User Map is injected...
 private ConcurrentHashMap<String, User> userMap;
 
 /**
  * Gets User Map
  *
  * @return ConcurrentHashMap User Map
  */
 public ConcurrentHashMap<String, User> getUserMap() {
  return userMap;
 }
 
 /**
  * Sets User Map
  *
  * @param ConcurrentHashMap User Map
  */
 public void setUserMap(ConcurrentHashMap<String, User> userMap) {
  this.userMap = userMap;
 }
 
}

ШАГ 7: СОЗДАЙТЕ ИНТЕРФЕЙС IUserService

Интерфейс IUserService, представляющий интерфейс службы пользователя, создан.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package com.otv.user.service;
 
import java.util.Collection;
 
import com.otv.common.exceptions.NonExistentUserException;
import com.otv.user.User;
 
/**
 *
 * User Service Interface
 *
 * @author  onlinetechvision.com
 * @since   19 May 2012
 * @version 1.0.0
 *
 */
public interface IUserService {
 
 /**
  * Adds User
  *
  * @param  User user
  * @return boolean whether delete operation is success or not.
  */
 boolean addUser(User user);
 
 /**
  * Deletes User
  *
  * @param  User user
  * @return boolean whether delete operation is success or not.
  */
 boolean deleteUser(User user);
 
 /**
  * Updates User
  *
  * @param  User user
  * @throws NonExistentUserException
  */
 void updateUser(User user) throws NonExistentUserException;
 
 /**
  * Gets User
  *
  * @param  String User Id
  * @return User
  */
 User getUserById(String id);
 
 /**
  * Gets User Collection
  *
  * @return List - User list
  */
 Collection<User> getUsers();
}

ШАГ 8: СОЗДАНИЕ КЛАССА UserService

Класс UserService создается путем реализации интерфейса IUserService.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
package com.otv.user.service;
 
import java.util.Collection;
import com.otv.cache.service.ICacheService;
import com.otv.common.exceptions.NonExistentUserException;
import com.otv.user.User;
 
/**
 *
 * User Service
 *
 * @author  onlinetechvision.com
 * @since   19 May 2012
 * @version 1.0.0
 *
 */
public class UserService implements IUserService {
 
 //CacheService is injected...
 private ICacheService cacheService;
 
 /**
  * Adds User
  *
  * @param  User user
  * @return boolean whether delete operation is success or not.
  */
 public boolean addUser(User user) {
 
  getCacheService().getUserMap().put(user.getId(), user);
  if(getCacheService().getUserMap().get(user.getId()).equals(user)) {
   return true;
  }
 
  return false;
 }
 
 /**
  * Deletes User
  *
  * @param  User user
  * @return boolean whether delete operation is success or not.
  */
 public boolean deleteUser(User user) {
  User removedUser = getCacheService().getUserMap().remove(user.getId());
  if(removedUser != null) {
   return true;
  }
  return false;
 }
 
 /**
  * Updates User
  *
  * @param  User user
  * @throws NonExistentUserException
  */
 public void updateUser(User user) throws NonExistentUserException {
  if(getCacheService().getUserMap().containsKey(user.getId())) {
   getCacheService().getUserMap().put(user.getId(), user);
  } else {
   throw new NonExistentUserException("Non Existent User can not update! User : "+user);
  }
 }
 
 /**
  * Gets User
  *
  * @param  String User Id
  * @return User
  */
 public User getUserById(String id) {
  return getCacheService().getUserMap().get(id);
 }
 
 /**
  * Gets User List
  *
  * @return Collection - Collection of Users
  */
 public Collection<User> getUsers() {
  return (Collection<User>) getCacheService().getUserMap().values();
 }
 
 /**
  * Gets Cache Service
  *
  * @return ICacheService - Cache Service
  */
 public ICacheService getCacheService() {
  return cacheService;
 }
 
 /**
  * Sets Cache Service
  *
  * @param ICacheService - Cache Service
  */
 public void setCacheService(ICacheService cacheService) {
  this.cacheService = cacheService;
 }
 
}

ШАГ 9: СОЗДАНИЕ КЛАССА UserServiceTester

Класс User Service Tester создается путем расширения AbstractTestNGSpringContextTests.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
package com.otv.user.service.test;
 
import junit.framework.Assert;
 
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
 
import com.otv.common.exceptions.NonExistentUserException;
import com.otv.user.User;
import com.otv.user.service.IUserService;
 
/**
 * User Service Tester Class
 *
 * @author  onlinetechvision.com
 * @since   19 May 2012
 * @version 1.0.0
 *
 */
@ContextConfiguration(locations={"classpath:applicationContext.xml"})
public class UserServiceTester extends AbstractTestNGSpringContextTests {
 
 private static Logger logger = Logger.getLogger(UserServiceTester.class);
 
 @Autowired
 private IUserService userService;
 
 private User firstUser;
 private User secondUser;
 private User thirdUser;
 
 /**
  * Creates Test Users
  *
  */
 private void createUsers() {
  firstUser = new User();
        firstUser.setId("1");
        firstUser.setName("Lionel");
        firstUser.setSurname("Messi");
 
        secondUser = new User();
        secondUser.setId("2");
        secondUser.setName("David");
        secondUser.setSurname("Villa");
 
        thirdUser = new User();
        thirdUser.setId("3");
        thirdUser.setName("Andres");
        thirdUser.setSurname("Iniesta");
 }
 
 /**
  * Asserts that User Properties are not null.
  *
  * @param User
  */
 private void assertNotNullUserProperties(User user) {
  Assert.assertNotNull("User must not be null!", user);
  Assert.assertNotNull("Id must not be null!", user.getId());
  Assert.assertNotNull("Name must not be null!", user.getName());
  Assert.assertNotNull("Surname must not be null!", user.getSurname());
 }
 
 /**
  * The annotated method will be run before any test method belonging to the classes
  * inside the <test> tag is run.
  *
  */
 @BeforeTest
    public void beforeTest() {
  logger.debug("BeforeTest method is run...");
 }
 
 /**
  * The annotated method will be run before the first test method in the current class
  * is invoked.
  *
  */
 @BeforeClass
    public void beforeClass() {
  logger.debug("BeforeClass method is run...");
  createUsers();
 }
 
 /**
  * The annotated method will be run before each test method.
  *
  */
 @BeforeMethod
    public void beforeMethod() {
  logger.debug("BeforeMethod method is run...");
 }
 
 /**
  * Tests the process of adding user
  *
  */
 @Test
 public void addUser() {
  assertNotNullUserProperties(firstUser);
  Assert.assertTrue("User can not be added! User : " + firstUser, getUserService().addUser(firstUser));
 }
 
 /**
  * Tests the process of querying user
  *
  */
 @Test
 public void getUserById() {
  User tempUser = getUserService().getUserById(firstUser.getId());
  assertNotNullUserProperties(tempUser);
  Assert.assertEquals("Id is wrong!", "1", tempUser.getId());
  Assert.assertEquals("Name is wrong!", "Lionel", tempUser.getName());
  Assert.assertEquals("Surname is wrong!", "Messi", tempUser.getSurname());
 }
 
 /**
  * Tests the process of deleting user
  *
  */
 @Test
 public void deleteUser() {
  assertNotNullUserProperties(secondUser);
  Assert.assertTrue("User can not be added! User : " + secondUser, getUserService().addUser(secondUser));
  Assert.assertTrue("User can not be deleted! User : " + secondUser, getUserService().deleteUser(secondUser));
 }
 
 /**
  * Tests the process of updating user
  * @throws NonExistentUserException
  *
  */
 @Test(expectedExceptions = NonExistentUserException.class)
 public void updateUser() throws NonExistentUserException {
  getUserService().updateUser(thirdUser);
 }
 
 /**
  * Test user count
  *
  */
 @Test
 public void getUserCount() {
  Assert.assertEquals(1, getUserService().getUsers().size());
 }
 
 /**
  * The annotated method will be run after all the test methods in the current class have been run.
  *
  */
 @AfterClass
    public void afterClass() {
  logger.debug("AfterClass method is run...");
 }
 
 /**
  * The annotated method will be run after all the test methods belonging to the classes inside the <test> tag have run.
  *
  */
 @AfterTest
    public void afterTest() {
  logger.debug("AfterTest method is run...");
 }
 
 /**
  * The annotated method will be run after each test method.
  *
  */
 @AfterMethod
    public void afterMethod() {
  logger.debug("AfterMethod method is run...");
 }
 
 /**
  * Gets User Service
  *
  * @return IUserService User Service
  */
 public IUserService getUserService() {
  return userService;
 }
 
 /**
  * Sets User Service
  *
  * @param IUserService User Service
  */
 public void setUserService(IUserService userService) {
  this.userService = userService;
 }
 
}

ШАГ 10: СОЗДАТЬ applicationContext.xml

Контекст приложения создается следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
 
 
 <!-- User Map Declaration -->
 <bean id="UserMap" class="java.util.concurrent.ConcurrentHashMap" />
 
 <!-- Cache Service Declaration -->
 <bean id="CacheService" class="com.otv.cache.service.CacheService">
  <property name="userMap" ref="UserMap"/>
 </bean>
 
 <!-- User Service Declaration -->
 <bean id="UserService" class="com.otv.user.service.UserService">
    <property name="cacheService" ref="CacheService"/>
 </bean>
</beans>

ШАГ 11: ЗАПУСК ПРОЕКТА

В этой статье был использован плагин TestNG Eclipse. Если вы используете Eclipse, его можно загрузить через страницу загрузки TestNG

Если UserServiceTester запущен, результаты тестов будут показаны следующим образом:

ШАГ 12: СКАЧАТЬ

OTV_SpringTestNG

РЕКОМЕНДАЦИИ :
Поддержка весеннего тестирования
TestNG Ссылка

Справка: поддержка весеннего тестирования с TestNG от нашего партнера по JCG Эрен Авсарогуллари в блоге Online Technology Vision .