Assertnull java что это
Перейти к содержимому

Assertnull java что это

  • автор:

Руководство по JUnit. Утверждения

При написании тестов мы практически всегда используем утверждения, большинство из которых находятся в классе Assert.

Данный класс содержит набор утверждений, которые крайне облегчают процесс тестирования. Записываются только те утверждения, которые не прошли.

Ниже приведены наиболее важные методы класса Assert:

Методы и описание
1
2 void assertTrue(boolean expected, boolean actual)

Рассмотрим простой пример:

Класс AssertionTests.java

 package net.proselyte.tutorials; import org.junit.Assert; import org.junit.Test; import static org.junit.Assert.*; /** * Simple test class that demonstrates in action * * @author Eugene Suleimanov * @version 1.0 */ public class AssertionTests < @Test public void shouldDemonstrateAssertionsTest() < Integer first = 1; Integer second = 2; Integer repeatFirst = 1; Integer[] expectedIntegerArray = ; Integer[] resultIntegerArray = ; assertEquals(first,repeatFirst); assertNotNull(second); assertSame(first, repeatFirst); assertArrayEquals(expectedIntegerArray, resultIntegerArray); > > 

junitassertiontestsresult

В результате работы данного теста мы получим следующий результат:

Аннотации

Здесь и в предыдущих примерах мы использовали аннотации.

Аннотации представляют собой, своего рода, теги, которые мы добавляем в код и применяем их к классам и методам. По назначению мы можем их разделить на следующие группы:

  • игнорируют методы и классы
  • запускаются перед и после всех методов
  • запускаются до и после всех тестовых методов

Сейчас мы подробно рассмотрим наиболее часто используемые из них:

Аннотации и описание
1 @Test

Рассмотрим следующий пример:
Создадим класс AnnotationTests.java

 package net.proselyte.tutorials.junit; import org.junit.*; /** * Test class to demonstrate annotations in action * * @author Eugene Suliemanov * @version 1.0 */ public class AnnotationTests < @BeforeClass public static void beforeClass()< System.out.println("This method has been executed first. "); >@AfterClass public static void afterClass() < System.out.println("This method has been executed last. "); >@Before public void before() < System.out.println("Before each test"); >@After public void after() < System.out.println("After each test"); >@Test public void simpleTest() < System.out.println("This is simple test"); >@Ignore @Test public void ignoreTest() < System.out.println("This test will be ignored"); >> 

В результате работы данного класса мы получим следующий результат:

junitassertiontestsresult

На этом мы заканчиваем изучение фреймворка JUnit.
Для более подробного изучения данной технологии крайне рекомендую вам изучить книгу “JUnit in Action”. Она даст хорошее понимание как самого фреймворка, так и примеров его использования.

5) Джунит Assert

Assert — это метод, полезный при определении статуса Pass или Fail тестового примера. Методы assert предоставляются классом org.junit.Assert, который расширяет класс java.lang.Object.

Существуют различные типы утверждений, такие как логические, нулевые, идентичные и т. Д.

Junit предоставляет класс с именем Assert, который предоставляет набор методов утверждений, полезных при написании тестовых случаев и для обнаружения неудачных тестов.

Методы assert предоставляются классом org.junit.Assert, который расширяет класс java.lang.Object .

В этом уроке вы узнаете

  • Методы JUnit Assert
  • логический
  • Нулевой объект
  • идентичный
  • Утвердить равными
  • Assert Array Equals
  • Сообщение об ошибке
  • JUnit assertEquals
  • Утверждения с плавающей точкой
  • Пример JUnit Assert

Методы JUnit Assert

логический

Если вы хотите проверить логические условия (true или false), вы можете использовать следующие методы assert

Здесь условие является логическим значением.

Нулевой объект

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

Здесь объект является Java- объектом, например, assertNull (фактический);

идентичный

Если вы хотите проверить, идентичны ли объекты (т. Е. Сравнивают две ссылки на один и тот же объект Java) или разные.

  1. assertSame (ожидаемый, фактический), он вернет true, если ожидается == фактический
  2. assertNotSame (ожидаемый, фактический)

Утвердить равными

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

  • assertEquals (ожидается, актуально)

Он вернет истину, если: Ожидается .

Assert Array Equals

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

  • assertArrayEquals (ожидается, актуально)

Вышеупомянутый метод должен использоваться, если массивы имеют одинаковую длину, для каждого действительного значения для i вы можете проверить его, как указано ниже:

  • assertEquals (ожидаемый [I], фактическая [I])
  • assertArrayEquals (ожидаемый [I], фактическая [I])

Сообщение об ошибке

Если вы хотите выбросить какую-либо ошибку подтверждения, у вас есть fail (), которая всегда приводит к отказу.

Вы можете использовать метод утверждения с дополнительным параметром String в качестве первого параметра. Эта строка будет добавлена ​​в сообщение об ошибке, если утверждение не выполнено. Например, ошибка (сообщение) может быть записана как

  • assertEquals (сообщение, ожидаемый, фактический)

JUnit assertEquals

У вас есть assertEquals (a, b), который опирается на метод equals () класса Object.

  • Здесь это будет оценено как a.equals (b).
  • Здесь тестируемый класс используется для определения подходящего отношения равенства.
  • Если класс не отменяет Equals () метод объект класса, то получите поведение по умолчанию равно () метод, т.е. идентичность объекта.

Если a и b являются примитивами, такими как byte , int , boolean и т. Д., То для assertEquals (a, b) будет сделано следующее:

a и b будут преобразованы в их эквивалентный тип объекта-обертки ( Byte, Integer , Boolean и т. д.), а затем будет выполнен анализ a.equals (b) .

Например: рассмотрим нижеприведенные строки, имеющие одинаковые значения, давайте проверим это с помощью assertTrue

String obj1="Junit"; String obj2="Junit"; assertEquals(obj1,obj2);

Выше оператор assert вернет true, так как obj1.equals (obj2) возвращает true.

Утверждения с плавающей точкой

Если вы хотите сравнить типы с плавающей запятой (например, double или float ), вам нужен дополнительный обязательный параметр delta, чтобы избежать проблем с ошибками округления при выполнении сравнений с плавающей запятой.

Утверждение оценивается как указано ниже:

assertEquals (aDoubleValue, anotherDoubleValue, 0,001)

Пример JUnit Assert

Ниже пример демонстрирует, как утверждать условие, используя методы JUnit assert.

Давайте создадим простой тестовый класс с именем Junit4AssertionTest.java и класс тестового бегуна TestRunner.java .

Вы создадите несколько переменных и важных утверждений assert в JUnit.

В этом примере вы выполните наш тестовый класс, используя TestRunner.java

Шаг 1) Давайте создадим класс, охватывающий все важные методы операторов assert в junit:

Junit4AssertionTest.java

package guru99.junit; import static org.junit.Assert.*; import org.junit.Test; public class Junit4AssertionTest < @Test public void testAssert()< //Variable declaration String string1="Junit"; String string2="Junit"; String string3="test"; String string4="test"; String string5=null; int variable1=1; int variable2=2; int[] airethematicArrary1 = < 1, 2, 3 >; int[] airethematicArrary2 = < 1, 2, 3 >; //Assert statements assertEquals(string1,string2); assertSame(string3, string4); assertNotSame(string1, string3); assertNotNull(string1); assertNull(string5); assertTrue(variable1 >

Шаг 2) Вам нужно создать класс бегуна для выполнения вышеупомянутого класса:

TestRunner.java

package guru99.junit; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure; public class TestRunner < public static void main(String[] args) < Result result = JUnitCore.runClasses(Junit4AssertionTest.class); for (Failure failure : result.getFailures()) < System.out.println(failure.toString()); >System.out.println(«Result= vertical-align: inherit;»> Шаг 3) Давайте шаг за шагом проанализируем ожидаемый результат:

Рассмотрим все утверждения assert одно за другим:

Теперь сравните string1 = «Junit» с string2 = «Junit» с методом equals объекта класса. Замена метода assertEquals из метода java.lang.Object.equals ():

string1.equals (string2) => возвращает true

Поэтому assertEquals (string1, string2) вернет true .

Функциональность «assertSame ()» заключается в проверке того, что два объекта ссылаются на один и тот же объект.

Поскольку string3 = «test» и string4 = «test» означает, что как string3, так и string4 относятся к одному типу, поэтому assertSame (string3, string4) вернет true .

  1. assertNotSame (строка1, строка3);

Функция «assertNotSame ()» заключается в проверке того, что два объекта не ссылаются на один и тот же объект.

Поскольку string1 = «Junit» и string3 = «test» означает, что и string1, и string3 относятся к разным типам, поэтому assertNotSame (string1, string3) вернет true .

Функциональность «assertNotNull ()» заключается в проверке того, что объект не является нулевым.

Так как string1 = «Junit», которое является ненулевым значением, assertNotNull (string1) вернет true .

Функциональность «assertNull ()» заключается в проверке того, что объект является нулевым.

Поскольку string5 = null, что является нулевым значением, assertNull (string5) вернет true .

Функциональность «assertTrue ()» заключается в проверке истинности условия.

  1. assertArrayEquals (airethematicArrary1, airethematicArrary2);

Функциональность «assertArrayEquals ()» заключается в проверке того, что ожидаемый массив и полученный массив равны. Тип массива может быть int, long, short, char, byte или java.lang.Object.

Поскольку airethematicArrary1 = и airethematicArrary2 = , который показывает, что оба массива равны, assertArrayEquals (airethematicArrary1, airethematicArrary2) вернет true

Поскольку все семь операторов assert класса Junit4AssertionTest.java возвращают значение true, поэтому при выполнении тестового класса assert он вернет успешный тест. (см. вывод ниже)

Шаг 4) Щелкните правой кнопкой мыши на Junit4AssertionTest.java и выберите runAs-> JUnit. Вы увидите вывод, как показано ниже:

Junit Assert

Выше вывод показывает успешный результат теста, как и ожидалось.

Резюме:

В этом руководстве вы изучили все важные типы методов утверждений, предоставляемых JUnit. Также вы видели примеры утверждений assert. Это показывает, что если все операторы assert возвращают значение true, то графический интерфейс пользователя теста вернет истинный результат, а в случае сбоя одного теста он вернет ошибочный результат.

Примеры утверждений JUnit 5

Это продолжение туториала по JUnit 5. Введение опубликовано здесь.

Утверждения (Assertions) JUnit 5 помогают сравнить ожидаемый результат с фактическим результатом теста. Для простоты все утверждения JUnit Jupiter являются статическими методами в классе org.junit.jupiter.Assertions.

Не успешные утверждения будет генерировать исключение AssertionFailedError или его подкласс.

Оглавление

  1. assertEquals() и assertNotEquals()
  2. assertArrayEquals()
  3. assertIterableEquals()
  4. assertLinesMatch()
  5. assertNotNull() и assertNull()
  6. assertNotSame() и assertSame()
  7. assertTimeout() и assertTimeoutPreemptively()
  8. assertTrue() и assertFalse)
  9. assertThrows()
  10. Пример fail()

1. assertEquals() и assertNotEquals()

Метод Assertions.assertEquals() используется для подтверждения того, что ожидаемое и фактическое значения равны. Метод assertEquals() ммеет много перегруженных методов для разных типов данных, например, int, short, float, char и т. д. Он также выдает сообщения об ошибках, которые будут напечатаны в случае если тест будет неуспешным. например

Перегруженные методы

public static void assertEquals(int expected, int actual) public static void assertEquals(int expected, int actual, String message) public static void assertEquals(int expected, int actual, Supplier

Примеры

void test() < //Тест пройдёт Assertions.assertEquals(4, Calculator.add(2, 2)); //Тест не пройдёт Assertions.assertEquals(3, Calculator.add(2, 2), "Calculator.add(2, 2) test failed"); //Тест не пройдёт SuppliermessageSupplier = () -> "Calculator.add(2, 2) test failed"; Assertions.assertEquals(3, Calculator.add(2, 2), messageSupplier); >

Точно так же метод Assertions.assertNotEquals() используется для утверждения, что ожидаемое и фактическое значения НЕ равны. В отличие от метода assertEquals() , assertNotEquals() не содержит перегруженных методов для разных типов данных, а только параметр типа Object принимается.

Перегруженные методы

public static void assertNotEquals(Object expected, Object actual) public static void assertNotEquals(Object expected, Object actual, String message) public static void assertNotEquals(Object expected, Object actual, Supplier messageSupplier)

Примеры

void test() < //Тест пройдёт Assertions.assertNotEquals(3, Calculator.add(2, 2)); //Тест не пройдёт Assertions.assertNotEquals(4, Calculator.add(2, 2), "Calculator.add(2, 2) test failed"); //Тест не пройдёт SuppliermessageSupplier = () -> "Calculator.add(2, 2) test failed"; Assertions.assertNotEquals(4, Calculator.add(2, 2), messageSupplier); >

2. assertArrayEquals()

Метод assertArrayEquals() утверждает, что ожидаемый и фактический массивы равны.

Он также имеет перегруженные методы для различных типов данных, например, boolean[], char[], int[] и т. д. Он также выдает сообщения об ошибках, которые будут напечатаны в случае сбоя теста. например

Перегруженные методы

public static void assertArrayEquals(int[] expected, int[] actual) public static void assertArrayEquals(int[] expected, int[] actual, String message) public static void assertArrayEquals(int[] expected, int[] actual, Supplier messageSupplier)

Примеры

void testCase() < //Тест пройдёт Assertions.assertArrayEquals(new int[], new int[], "Array Equal Test"); //Тест не пройден, потому что порядок элементов отличается Assertions.assertArrayEquals(new int[], new int[], "Array Equal Test"); //Тест не пройден, потому что количество элементов другое Assertions.assertArrayEquals(new int[], new int[], "Array Equal Test"); >

3. assertIterableEquals()

Метод assertIterableEquals() утверждает,, что ожидаемые и фактические итерации полностью равны. «Глубокое равенство» означает, что количество и порядок элементов в коллекции должны быть одинаковыми, а повторяющиеся элементы должны быть одинаковыми.

У него также есть три перегруженных метода.

Перегруженные методы

public static void assertIterableEquals(Iterable expected, Iterable> actual) public static void assertIterableEquals(Iterable expected, Iterable> actual, String message) public static void assertIterableEquals(Iterable expected, Iterable> actual, Supplier messageSupplier)

Примеры

@Test void testCase() < IterablelistOne = new ArrayList<>(Arrays.asList(1,2,3,4)); Iterable listTwo = new ArrayList<>(Arrays.asList(1,2,3,4)); Iterable listThree = new ArrayList<>(Arrays.asList(1,2,3)); Iterable listFour = new ArrayList<>(Arrays.asList(1,2,4,3)); //Тест пройдёт Assertions.assertIterableEquals(listOne, listTwo); //Тест не пройдёт Assertions.assertIterableEquals(listOne, listThree); //Тест не пройдёт Assertions.assertIterableEquals(listOne, listFour); >

4. assertLinesMatch()

Он утверждает, что ожидаемый список строк соответствует фактическому списку. Логика сопоставления строки с другой строкой:

  1. проверьте, если expected.equals(actual) - если да, переходите к следующей паре
  2. в противном случае рассматривать expected как регулярное выражение и проверять переход String.matches(String) - если да, переходить к следующей паре
  3. в противном случае проверьте, является ли expected строка маркером быстрой перемотки вперед, если да, примените соответствующие строки быстрой перемотки вперед и перейдите к 1.

Допустимый маркер быстрой перемотки вперед - это строка, которая начинается и заканчивается >> и содержит не менее четырех символов. Любой символ между литералами быстрой перемотки вперед отбрасывается.

>>>> >> stacktrace >> >> single line, non Integer.parse()-able comment >>

5. assertNotNull() и assertNull()

AssertNotNull() утверждает, что фактическое значение НЕ равно нулю. Точно так же метод assertNull() утверждает, что это действительно так null . У обоих есть три перегруженных метода.

Перегруженные методы

public static void assertNotNull(Object actual) public static void assertNotNull(Object actual, String message) public static void assertNotNull(Object actual, Supplier messageSupplier) public static void assertEquals(Object actual) public static void assertEquals(Object actual, String message) public static void assertEquals(Object actual, Supplier messageSupplier)

Примеры

@Test void testCase() < String nullString = null; String notNullString = "howtodoinjava.com"; //Test will pass Assertions.assertNotNull(notNullString); //Test will fail Assertions.assertNotNull(nullString); //Test will pass Assertions.assertNull(nullString); // Test will fail Assertions.assertNull(notNullString); >

6. assertNotSame() и assertSame()

assertNotSame() утверждает, что ожидаемый и фактический не относятся к одному объекту. Точно так же метод assertSame() утверждает, что ожидаемый и фактический относятся к одному и тому же объекту.

У обоих есть три перегруженных метода.

Перегруженные методы

public static void assertNotSame(Object expected, Object actual) public static void assertNotSame(Object expected, Object actual, String message) public static void assertNotSame(Object expected, Object actual, Supplier<> messageSupplier) public static void assertSame(Object expected, Object actual) public static void assertSame(Object expected, Object actual, String message) public static void assertSame(Object expected, Object actual, Supplier messageSupplier)

Примеры

@Test void testCase() < String originalObject = "howtodoinjava.com"; String cloneObject = originalObject; String otherObject = "example.com"; //Test will pass Assertions.assertNotSame(originalObject, otherObject); //Test will fail Assertions.assertNotSame(originalObject, cloneObject); //Test will pass Assertions.assertSame(originalObject, cloneObject); // Test will fail Assertions.assertSame(originalObject, otherObject); >

7. assertTimeout() и assertTimeoutPreemptively()

Методы assertTimeout() и assertTimeoutPreemptively() используются для тестирования долго выполняющихся задач. Если заданная задача в тесте занимает больше указанной продолжительности, тест завершится неудачно.

Единственная разница между обоими методами заключается в том, что в assertTimeoutPreemptively() выполнение Executable или ThrowingSupplier будет прервано с упреждением при превышении тайм-аута. В случае assertTimeout() , Executable или ThrowingSupplier не будет прервана.

Перегруженные методы

public static void assertTimeout(Duration timeout, Executable executable) public static void assertTimeout(Duration timeout, Executable executable, String message) public static void assertTimeout(Duration timeout, Executable executable, Supplier messageSupplier) public static void assertTimeout(Duration timeout, ThrowingSupplier supplier, String message) public static void assertTimeout(Duration timeout, ThrowingSupplier supplier, Supplier messageSupplier)

Примеры

@Test void testCase() < //This will pass Assertions.assertTimeout(Duration.ofMinutes(1), () ->< return "result"; >); //This will fail Assertions.assertTimeout(Duration.ofMillis(100), () -> < Thread.sleep(200); return "result"; >); //This will fail Assertions.assertTimeoutPreemptively(Duration.ofMillis(100), () -> < Thread.sleep(200); return "result"; >); >

8. assertTrue() и assertFalse()

Метод assertTrue() утверждает, что предоставленное условие истинно или предоставленное логическое условие BooleanSupplier истинно.

Точно так же assertFalse() утверждает, что предоставленное условие ложно.

У обоих есть следующие перегруженные методы:

Перегруженные методы

public static void assertTrue(boolean condition) public static void assertTrue(boolean condition, String message) public static void assertTrue(boolean condition, Supplier messageSupplier) public static void assertTrue(BooleanSupplier booleanSupplier) public static void assertTrue(BooleanSupplier booleanSupplier, String message) public static void assertTrue(BooleanSupplier booleanSupplier, Supplier messageSupplier) public static void assertFalse(boolean condition) public static void assertFalse(boolean condition, String message) public static void assertFalse(boolean condition, Supplier messageSupplier) public static void assertFalse(BooleanSupplier booleanSupplier) public static void assertFalse(BooleanSupplier booleanSupplier, String message) public static void assertFalse(BooleanSupplier booleanSupplier, Supplier messageSupplier)

Примеры

@Test void testCase() < boolean trueBool = true; boolean falseBool = false; Assertions.assertTrue(trueBool); Assertions.assertTrue(falseBool, "test execution message"); Assertions.assertTrue(falseBool, AppTest::message); Assertions.assertTrue(AppTest::getResult, AppTest::message); Assertions.assertFalse(falseBool); Assertions.assertFalse(trueBool, "test execution message"); Assertions.assertFalse(trueBool, AppTest::message); Assertions.assertFalse(AppTest::getResult, AppTest::message); >private static String message () < return "Test execution result"; >private static boolean getResult ()

9. assertThrows()

assetThrows() утверждает, что исполнение подаваемы Executable генерирует исключение из expectedType и возвращает исключение.

Перегруженные методы

public static T assertThrows(Class expectedType, Executable executable)

Примеры

@Test void testCase() < Throwable exception = Assertions.assertThrows(IllegalArgumentException.class, () ->< throw new IllegalArgumentException("error message"); >); >

10. Пример fail()

Метод fail() делает тест неуспешным. Он имеет следующие перегруженные методы:

Перегруженные методы

public static void fail(String message) public static void fail(Throwable cause) public static void fail(String message, Throwable cause) public static void fail(Supplier messageSupplier)

Примеры

public class AppTest < @Test void testCase() < Assertions.fail("not found good reason to pass"); Assertions.fail(AppTest::message); >private static String message () < return "not found good reason to pass"; >>

Утверждения — Java: Автоматическое тестирование

Каждую проверку, которую мы написали для метода StringUtils.capitalize() , в тестировании принято называть утверждением (assert). Утверждения — ключевая часть тестов. Именно они проверяют работу кода:

// Первое утверждение (проверка на пустую строку) if (!"".equals(StringUtils.capitalize("")))  throw new AssertionError("Метод работает неверно!"); > // Второе утверждение (проверка на слово) if (!"Hello".equals(StringUtils.capitalize("hello")))  throw new AssertionError("Метод работает неверно!"); > 

Можно заметить, что все проверки строятся одинаковым способом: условие => исключение. Java, начиная с версии 1.4., поддерживает ключевое слово assert, которое предназначено для проверки утверждений:

// Проверка сменилась с отрицательной на положительную // Утверждение считается пройденным, если условие истинно assert 4 == 2 + 2; assert "".equals(StringUtils.capitalize("")); // Опциональное сообщение об ошибке // Указывается после двоеточия assert "Hello".equals(StringUtils.capitalize("hello")) : "Ваш метод не работает!"; 

Синтаксис достаточно прост:

  1. указываем ключевое слово assert,
  2. пишем выражение или вызываем метод, результатом которого будет булево выражение ( true или false ),
  3. опционально: после двоеточия можем указать некоторое строковое сообщение, которое будет передано вместе с ошибкой. В общем случае может быть не просто строка, а любое выражение, которое возвращает что-то отличное от void .

В случае если значение после ключевого слова assert будет равно false , то возникнет ошибка (будет выброшено AssertionError ). Другими словами, assert true означает что всё хорошо, а assert false говорит об ошибке. Например, если в последнем примере метод StringUtils.capitalize("hello") вернёт что-то отличное от Hello, то мы увидим в консоли вот такое сообщение:

java.lang.AssertionError: Ваш метод не работает! at io.hexlet.LessonTest.testMain(LessonTest.java:12) . 

В первой строке мы видим какое исключение было проброшено ( java.lang.AssertionError ) и сообщение, которое мы передали вместе с ним. Кроме сообщения, выводится бектрейс, по которому можно найти сработавшее утверждение. В данном случае необходимо изучать код на 12 строке в классе io.hexlet.LessonTest .

Использование ключевого слова assert сделало наш код короче и проще для восприятия. Положительная проверка смотрится естественнее, так как это то, что мы ожидаем.

Однако, ключевое слово assert было введено только в Java 1.4., это значит что в предыдущих версиях Java вполне можно было создать переменную или метод с именем assert. Программы в которых использовались такие имена могли стать неработоспособными после введения нового ключевого слова. Для сохранения обратной совместимости было принято решение, что по умолчанию механизм использования assert будет отключен. Если нужно чтобы ваши assert срабатывали, то при запуске программы указывается аргумент командной строки -enableassertions ( -ea ).

Рассмотрим пример. Допустим у нас есть вот такой класс:

class HelloWorld  public static void main(String[] args)  assert 1 == 2; // заведомо ложное утверждение System.out.println("Hello world"); > > 

Если мы его скомпилируем и запустим без дополнительных аргументов, то мы увидим на экране текст Hello world, несмотря на то, что 1 точно не равно 2. Чтобы включить assert нам необходимо сделать так:

-ea HelloWorld.java # Boom! 

Тогда в консоли вместо надписи Hello world мы увидим сообщение об ошибке:

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов

Наши выпускники работают в компаниях:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *