Разработването на нови функции може да бъде пълен взрив, но може да бъде и бавен и разочароващ процес. Един от най-значимите фактори, допринасящи за това разочарование, е времето, необходимо за преминаване през всеки цикъл на разработка. Колкото повече време отнема разработването, тестването и усъвършенстването на всяка функция, толкова повече време се губи и толкова по-бавен става напредъкът.

Но какво ще стане, ако ви кажа, че има начин да намалите значително времето си за повторение? Днес ще проучим техника, която може да ви помогне да „фалшифицирате, докато успеете“, когато става въпрос за разработване на функции: използване на фалшиви данни, мъничета и фалшификати. Този подход ще ви помогне да премахнете зависимостта от външен код или ресурси, които не са необходими в момента, и ще ви позволи да се съсредоточите върху задачата.

Защо намаляването на времето за итерация е от решаващо значение

Намаляването на времето за итерация е от решаващо значение поради няколко причини:

  1. По-бърз MVP: Чрез бързото разработване на работещ минимално жизнеспособен продукт (MVP) можете да съберете обратна връзка от реалния свят и да вземете решения, базирани на данни, за това кои функции са съществени и кои не. По този начин можете да адаптирате и промените своя продукт според действителната обратна връзка от вашия опит с функцията, вместо да губите време за ненужни добавки, без да сте сигурни, че основната функционалност работи.
  2. Повишена производителност: Когато прекарвате по-малко време в чакане за външни зависимости, можете да се съсредоточите върху това, което наистина има значение: писане и усъвършенстване на вашия код.
  3. По-голяма гъвкавост: Когато не разчитате на външен код или ресурси, можете да правите промени и подобрения по-лесно, което ви позволява да променяте, когато е необходимо, и да се адаптирате към новите изисквания.
  4. Подобрен морал: Няма нищо по-лошо от това да останеш в безкраен цикъл на развитие. Чрез намаляване на времето за повторение можете да поддържате инерция и да поддържате екипа си мотивиран.

Сега, след като разгледахме защо е от съществено значение да намалим времето за повторение, нека да се потопим в това какво всъщност представляват фиктивните данни, мъничетата и фалшификаторите.

Фалшиви данни, заглушки и фалшификати: градивните елементи на бързото развитие

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

Фалшиви данни

Фалшивите данни са набор от фалшиви точки с данни, които можете да използвате, за да симулирате поведението на вашето приложение. Помага ви да избегнете разчитането на реални източници на данни, които могат да бъдат бавни или недостъпни по време на разработката. Като използвате фиктивни данни, можете да разработите и тествате логиката на вашето приложение независимо от всякакви външни зависимости.

пънчета

Плъзгачите са опростени версии на компоненти или функции, които връщат предварително определен отговор. Те ви помагат да изолирате конкретни части от вашето приложение и да се съсредоточите върху функционалността, която разработвате в момента. Пънчетата могат да се използват за дефиниране на структурата на вашия код, което ви позволява да продължите напред, без да се забивате в изпълнението на всяка отделна функция. Те също са полезни, когато си сътрудничите с други членове на екипа, които отговарят за разработването на определени функционалности.

Фалшиви

Фалшификаторите са библиотеки или инструменти, които генерират реалистично изглеждащи данни за целите на тестването. Те могат да създават данни, които приличат на информация от реалния свят, като имена, адреси и дати, без да използват действителни точки от данни.

Разбиране на взаимодействието между фиктивни данни, заглушки и фалшификати

След като вече знаем какво представляват фиктивните данни, мъничетата и фалшификаторите, нека обсъдим как те взаимодействат и се допълват взаимно в процеса на разработка.

  • Фиктивните данни представляват структурата на данните и осигуряват начин за симулиране на поведението на приложението. Това е основата за изграждане на тестови сценарии и разбиране как вашето приложение трябва да реагира на различни входове.
  • Пънчетата заместват части от вашето приложение, които зависят от външни компоненти или услуги. Те ви помагат да се съсредоточите върху функционалността, която разработвате в момента, като осигуряват предвидимо поведение.
  • Фалшификатите генерират реалистични данни, за да попълнят вашите фиктивни данни и мъничета. Това ви позволява да създавате по-разнообразни и сложни тестови сценарии, без да създавате ръчно всяка отделна точка от данни.

Като комбинирате тези три техники, можете да създадете гъвкава и ефективна среда за разработка, която ви позволява бързо да итерирате вашите функции, като същевременно се фокусирате върху действителната логика.

Събиране на всичко заедно: Практически пример

Сега ще разгледаме практически пример за това как може да се приложи всяка от тези техники. Избрахме JavaScript за простота, но засега можете да третирате този пример като псевдокод.

Да приемем, че изграждаме просто приложение, което показва списък с потребители и техните подробности. Ще използваме фиктивни данни, мъничета и фалшификати, за да създадем бърза среда за разработка за този сценарий.

Стъпка 1: Създаване на фиктивни данни

Първо, трябва да създадем някои фиктивни данни, които да представят потребителската информация. За този пример ще дефинираме прост JSON обект с потребителски данни:

[
 {
   “id”: 1,
   “name”: “John Doe”,
   “email”: “[email protected]”,
   “address”: “123 Main St, Anytown, USA”
 },
 {
   “id”: 2,
   “name”: “Jane Doe”,
   “email”: “[email protected]”,
   “address”: “456 Oak St, Anytown, USA”
 }
]

Стъпка 2: Внедряване на Stubs

Сега, след като имаме нашите фиктивни данни, можем да създадем функция за мъниче, която симулира извличане на потребителски данни от сървър:

function fetchUsers() {
 return new Promise((resolve) => {
   setTimeout(() => {
     resolve([
       {
         “id”: 1,
         “name”: “John Doe”,
         “email”: “[email protected]”,
         “address”: “123 Main St, Anytown, USA”
       },
       {
         “id”: 2,
         “name”: “Jane Doe”,
         “email”: “[email protected]”,
         “address”: “456 Oak St, Anytown, USA”
       }
     ]);
   }, 1000);
 });
}

В този пример функцията fetchUsers() връща обещание, което разрешава с фиктивните данни след забавяне от 1 секунда. Това симулира асинхронно API повикване, което ни позволява да разработим и тестваме нашето приложение, без да разчитаме на реален сървър.

Пример: Използване на fetchUsers() Stub

За да демонстрираме използването на функцията fetchUsers() stub, нека създадем проста функция, която показва извлечените потребителски данни:

async function displayUsers() {
  const users = await fetchUsers();
  users.forEach((user) => {
    console.log(`${user.name} (${user.email}): ${user.address}`);
 });
}

displayUsers();

Този пример извиква функцията fetchUsers() stub и след това регистрира данните за потребителя в конзолата.

Представете си, ако трябваше да изчакаме сървър или база данни да отговори, за да тестваме нашата displayUsers() функция, и внезапно източникът на данни престане да реагира или връзката ви с интернет прекъсне.
Добре, че вече не разчитаме на такива неща (:

Стъпка 3: Използване на фалшификати

За да направим нашия пример по-реалистичен, можем да използваме фалшива библиотека, за да генерираме по-голям набор от потребителски данни. Ето как можем да използваме популярната библиотека `Faker.js`, за да създадем по-разнообразен набор от фалшиви потребители:

import faker from ‘faker’;

function generateUsers(count) {
  const users = [];
  for (let i = 0; i < count; i++) {
    users.push({
      id: i + 1,
      name: faker.name.findName(),
      email: faker.internet.email(),
      address: faker.address.streetAddress()
    });
  }

  return users;
}

const mockUsers = generateUsers(50);

Сега нашето приложение има по-реалистичен набор от потребителски данни, с които да работим, което ни позволява да тестваме различни сценарии и крайни случаи.

Чрез комбиниране на фиктивни данни, мъничета и фалшификати можем да създадем среда за бърза разработка, която се фокусира върху функционалността, която разработваме в момента.

Най-добри практики и потенциални клопки

Нека се потопим в някои най-добри практики и потенциални капани, които трябва да знаете, докато работите с тези техники.

Поддържайте своите макетни данни реалистични

Когато създавате фиктивни данни, важно е да ги поддържате възможно най-реалистични. Това помага да се гарантира, че вашите тестове и опит в разработката много наподобяват сценарии от реалния свят. Например, ако работите върху проект, който се занимава с потребителски профили, създайте фиктивни данни, които включват различни имена, възрасти и друга подходяща информация, вместо да използвате общи контейнери като „John Doe“ или „12345“.

const realisticUsers = [
  { name: ‘Alice’, age: 28, email: ‘[email protected]’ },
  { name: ‘Bob’, age: 34, email: ‘[email protected]’ },
  { name: ‘Carol’, age: 22, email: ‘[email protected]’ },
];

Не прекалявайте с Stubs

Пънчетата могат да бъдат невероятно полезни, когато става въпрос за ускоряване на процеса на разработка и изолиране на различни части от кода ви. Въпреки това е важно да не прекалявате с тях. Прекомерното използване на мъничета може да доведе до прекалено твърд код, който е труден за поддръжка и преработване. Не забравяйте, че мъничетата са средство за постигане на цел - те трябва да ви помогнат да се съсредоточите върху най-критичните части от кода си и да избегнете затъването в подробности за изпълнението.

Отнасяйте се към мъничетата като към „празни кутии“, когато дойде времето, все пак трябва да ги напълните със съдържанието им.

Поддържайте вашите фалшификатори последователни

Когато използвате фалшификати за генериране на произволни данни, от съществено значение е да поддържате последователност във вашите тестове и среда за разработка. Непоследователните фалшиви данни могат да доведат до фалшиви отрицателни или положителни резултати във вашите тестове, което прави предизвикателство да се определи дали кодът ви функционира правилно. За да осигурите последователност, помислете за използване на начални стойности, когато инициализирате вашите фалшиви, така че едни и същи данни да се генерират всеки път, когато изпълнявате вашите тестове.

const faker = require(‘faker’);

faker.seed(12345); // Seed the random number generator

const firstName = faker.name.firstName(); // This will always generate the same first name
const lastName = faker.name.lastName(); // This will always generate the same last name

Популярни библиотеки и инструменти за фиктивни данни, заглушки и фалшификати

Обсъдихме значението на тези техники и сега е време да видим някои примери за библиотеки и инструменти, които можете да използвате в различни езици за програмиране, за да ви помогнат да постигнете това. Целта е да се покаже как тези концепции са приложими в различни среди за програмиране. Въпреки това ще наблегнем повече на C# и Unity3D, тъй като това са основните инструменти, използвани от моя екип в Magnifica VR.

C# и Unity3D

  • NSubstitute: Удобен заместител на .NET подигравателни библиотеки, NSubstitute е проектиран като по-ясна и по-кратка алтернатива на други подиграващи библиотеки, което улеснява създаването на заместители на интерфейси и класове във вашите тестове.
  • Moq: Популярна и лесна за използване подигравателна библиотека за .NET, която ви позволява да създавате фалшиви обекти, да задавате очаквания за тях и да проверявате взаимодействията с тях във вашите тестове.
  • Unity Test Framework:Unity3D предоставя вградена тестова рамка, която поддържа единица, интеграция и тестване от край до край. Тя ви позволява да създавате тестови двойници, като мъничета и фалшификати, за да изолирате тествания код и да премахнете зависимостите.

JavaScript

  • Faker.js: Популярна библиотека за генериране на фалшиви данни, като имена, адреси и телефонни номера. Може да се използва в комбинация с мъничета за създаване на реалистични фиктивни данни за вашите тестове.
  • Sinon.js: Библиотека, която предоставя самостоятелни тестови шпиони, мъничета и мокове за JavaScript. Работи с всяка рамка за тестване на модули и е съвместим с различни браузъри.

Python

  • Faker: Библиотека на Python, която генерира фалшиви данни за вас, подобно на Faker.js за JavaScript. Полезно е за създаване на фиктивни данни за тестване или попълване на бази данни.
  • unittest.mock: Вградена библиотека в Python, която ви позволява да създавате мъничета и макети за вашите тестове. Той е лесен за използване и не изисква никакви външни зависимости.

Рубин

  • Фалшив: Библиотека на Ruby, която генерира фалшиви данни, като имена, адреси и телефонни номера. Полезно е за създаване на реалистични фиктивни данни за вашите тестове или за зареждане на вашата база данни.
  • RSpec Mocks: Библиотека, която предоставя проста и гъвкава макетна рамка за Ruby. Той е част от екосистемата за тестване на RSpec и може да се използва с други библиотеки на RSpec или като самостоятелно решение за подигравки.

Както можете да видите, без значение с какъв език за програмиране работите, има налични библиотеки и инструменти, които да ви помогнат да създавате фиктивни данни, мъничета и фалшиви данни. Използването на тези инструменти ще ви спести време и ще направи процеса на тестване по-ефективен.

Сега, след като проучихме наличните инструменти и библиотеки, нека видим как всички тези концепции могат да бъдат приложени в сценарий от реалния свят.

Казус от практиката: Внедряване на фалшиви данни, заглушки и фалшификати в Unity3D проект

Нека разгледаме прост казус в проект на Unity3D. Ще създадем проста игра, която показва списък с играчи с техните резултати, и ще използваме концепциите, които току-що обсъдихме, за да ускорим процеса на разработка и да го направим по-ефективен.

Настройка на проекта

За да започнем, нека създадем нов Unity3D проект и да настроим основната структура. Ще ни трябва скрипт, който да обработва данните на играча, и друг, който да ги показва на екрана.

Създайте нов C# скрипт, наречен PlayerData.cs и добавете следния код:

public class PlayerData
{
  public string Name;
  public int Score;
}

Този прост клас ще съдържа името и резултата на играча. Сега нека създадем друг скрипт, наречен PlayerListDisplay.cs, за да покаже списъка с играчи на екрана. В този скрипт ще ни трябва функция, която взема списък от PlayerData обекти и ги показва:

using UnityEngine;
using System.Collections.Generic;

public class PlayerListDisplay : MonoBehaviour
{
  public void DisplayPlayers(List<PlayerData> players)
  {
    foreach (PlayerData player in players)
    {
      Debug.Log($”{player.Name}: {player.Score}”);
    }
  }
}

Създаване на файл за данни на играча

В този момент имаме нужда от някои данни, които да покажем на екрана. В сценарий от реалния свят можем да извлечем тези данни от сървър или база данни. Ние обаче не искаме да зависим от външен източник, докато разработваме и тестваме нашата функция за показване. Вместо това, нека създадем мъниче, което генерира списък с фалшиви играчи с произволни резултати.

Създайте нов C# скрипт, наречен PlayerDataStub.cs и добавете следния код:

using System.Collections.Generic;

public class PlayerDataStub
{
  public List<PlayerData> GenerateFakePlayers(int count)
  {
    List<PlayerData> fakePlayers = new List<PlayerData>();
    
    for (int i = 0; i < count; i++)
    {
      PlayerData player = new PlayerData
      {
        Name = $”Player {i + 1}”,
        Score = Random.Range(0, 100)
      };
      
      fakePlayers.Add(player);
    }
    
    return fakePlayers;
  }
}

С този мъниче можем да генерираме списък с фалшиви играчи, за да тестваме нашата функция DisplayPlayers, без да разчитаме на външни източници на данни.

Тестване на функцията на дисплея

Сега нека тестваме функцията DisplayPlayers, като й предоставим фалшивите данни, генерирани от нашия мъниче. Променете скрипта PlayerListDisplay.cs, както следва:

using UnityEngine;
using System.Collections.Generic;

public class PlayerListDisplay : MonoBehaviour
{
  private PlayerDataStub _playerDataStub;
  
  private void Start()
  {
    _playerDataStub = new PlayerDataStub();
    
    List<PlayerData> fakePlayers = _playerDataStub.GenerateFakePlayers(10);
    DisplayPlayers(fakePlayers);
  }
  
  public void DisplayPlayers(List<PlayerData> players)
  {
    foreach (PlayerData player in players)
    {
      Debug.Log($”{player.Name}: {player.Score}”);
    }
  }
}

С тази настройка можем бързо да тестваме и итерираме нашата функция DisplayPlayers, без да се тревожим за външни зависимости.

Представяме ви Faker за по-реалистични данни

Въпреки че нашето мъниче генерира фалшиви данни за играчи, имената и резултатите може да не са много реалистични. За да подобрим качеството на нашите тестови данни, можем да въведем фалшива библиотека като Bogus. Тази библиотека може да генерира по-реалистични имена и други данни, което прави нашите тестове по-представителни за сценарии от реалния свят.

Първо добавете пакета Bogus към вашия Unity3D проект с помощта на мениджъра на пакети. След това променете скрипта PlayerDataStub.cs, за да използвате библиотеката Bogus:

using System.Collections.Generic;
using Bogus;

public class PlayerDataStub
{
  private Faker _faker;
  
  public PlayerDataStub()
  {
    _faker = new Faker();
  }
  
  public List<PlayerData> GenerateFakePlayers(int count)
  {
    List<PlayerData> fakePlayers = new List<PlayerData>();
  
    for (int i = 0; i < count; i++)
    {
      PlayerData player = new PlayerData
      {
        Name = _faker.Name.FullName(),
        Score = _faker.Random.Number(0, 100)
      };
      
      fakePlayers.Add(player);
    }
  
    return fakePlayers;
  }
}

Сега нашето мъниче генерира по-реалистични данни за играчи, което ни позволява да тестваме нашата функция DisplayPlayers при по-точни условия.

Заключение

В този казус демонстрирахме как да използваме фиктивни данни, мъничета и фалшификати в Unity3D проект. Чрез създаване на мъниче за данни на играч и използване на фалшива библиотека за генериране на по-реалистични тестови данни, успяхме бързо да повторим нашата функция DisplayPlayers, без да разчитаме на външни източници на данни.

Внедряването на тези техники във вашите проекти може да ви помогне да спестите време и да намалите зависимостите, което ви позволява да се съсредоточите върху изграждането на основната функционалност на вашето приложение.

Обобщавайки

В тази публикация обсъдихме значението на намаляването на времето за повторение при разработването на нови функции. Разгледахме как използването на фиктивни данни, мъничета и фалшификати може да ви помогне да постигнете това чрез минимизиране на зависимостите от външни източници на данни или код, който все още не е внедрен.

Чрез разбирането и прилагането на тези техники можете да се съсредоточите върху изграждането на основната функционалност на вашето приложение, да повторите по-бързо и да се адаптирате към реалната обратна връзка по-рано. Не забравяйте, че е от съществено значение да имате работещ MVP възможно най-бързо, така че да можете да модифицирате и подобрите своя продукт въз основа на действителния опит и обратна връзка.

Не се страхувайте да го фалшифицирате, докато не успеете, и приятно кодиране!