Проблемы тестирования децентрализованных приложений
Во время работы над одним из новых проектов Jet Protocol стало очевидным, что в экосистеме отсутствуют некоторые базовые инструменты, необходимые для проведения сквозного тестирования приложений Solana dApps. Solana не одинока в решении этой проблемы, поскольку большинство сред децентрализованных приложений требуют от пользователя одобрения или подписания транзакций путем взаимодействия с кошельком.
Если транзакция не подписана закрытым ключом пользователя, сеть не может принять транзакцию.
Это ставит добросовестного web3-разработчика в затруднительное положение.
С одной стороны, существующие системы автоматизации (например, Cypress, Puppetteer, Selenium) не очень хорошо справляются с взаимодействующими браузерными расширениями, и чтобы заставить их работать, нужно создавать сложные настройки с несколькими экземплярами тестового бегуна (один для приложения и один для расширения) и как-то синхронизировать их. Грязно. Ненадежно.
С другой стороны, децентрализованные приложения чаще всего имеют дело с транзакциями определенной стоимости, будь то токены, NFT или что-то еще, поэтому вы хотите быть уверены, что ваше приложение пуленепробиваемо.
Так что же делать вам (нам)?
Не изобретать колесо. Я повторяю. Не изобретайте колесо.
Пабло Пикассо однажды сказал:
Хорошие художники копируют, великие художники крадут 🧑🎨.
Оказывается, в комнате всегда есть кто-то умнее вас. Это на сотни порядков вернее, если эта комната такая же большая, как Интернет.
Отличный парень по имени Остин Гриффит уже решил эту проблему для блокчейна Ethereum. Он разработал провайдера горелки, который генерировал закрытый ключ в браузере и позволял разработчику не взаимодействовать с расширением, если это необходимо (как в случае с тестированием E2E, но есть и другие варианты использования).
Мы сделали то же самое для блокчейна Solana (спасибо Остину!).
Представляем @jet-lab/e2e-react-adapter
.
На данном этапе я мог бы просто дать ссылку на репозиторий @jet-lab/e2e-react-adapter
и на этом закончить, поскольку я не очень привык писать посты в блогах. Но я постараюсь рассказать вам все вкратце, если вы потерпите.
Этот пакет предназначен для работы с провайдером Solana react, но вы должны быть в состоянии заставить его работать с другими реализациями (с некоторыми изменениями).
Вот как выглядит типичный Solana react dApp.
import { WalletProvider } from '@solana/wallet-adapter-react';
import {
PhantomWalletAdapter,
MathWalletAdapter,
SolflareWalletAdapter,
SolongWalletAdapter,
SolletWalletAdapter
} from '@solana/wallet-adapter-wallets';
import { useMemo } from 'react';
import YourMainApplication from './Main'
export function App(): JSX.Element {
const wallets = useMemo(() => [
new PhantomWalletAdapter(),
new MathWalletAdapter(),
new SolflareWalletAdapter(),
new SolongWalletAdapter(),
new SolletWalletAdapter(),
new SlopeWalletAdapter(),
]}, []);
return <WalletProvider wallets={wallets} autoConnect>
<YourMainApplication />
</WalletProvier>
}
Чтобы включить e2e тестирование, все, что вам нужно сделать, это установить пакет и добавить его в массив адаптеров (возможно, только на ваших staging / devnet развертываниях).
// Other imports
import { E2EWalletAdapter } from 'e2e-react-adapter';
export function App(): JSX.Element {
const isDev = true // set your devnet logic here
const wallets = useMemo(() => [
// other adapters
new E2EWalletAdapter()
]}, [isDev]);
return <WalletProvider wallets={wallets} autoConnect>
<YourMainApplication />
</WalletProvier>
}
Теперь вы сможете писать сквозные тесты для ваших Solana dApps!
Я солгал, вы еще не закончили. Но почти!
Поскольку пакет предназначен для сквозного тестирования в devnet / localnet, вы хотите, чтобы транзакции действительно проходили через сеть, а не просто взаимодействовали с узлом rpc. Но для этого нужен SOL для обеспечения транзакций.
Здесь у вас есть два варианта.
Один из них заключается в том, чтобы в вашем devnet dApp было место, где вы можете по воздуху передать немного SOL на ваш блестящий новый адаптер горелки. Это будет выглядеть примерно так:
import { useConnection, useWallet } from '@solana/wallet-adapter-react';
const RequestAirdrop = () => {
const { connection } = useConnection();
const { publicKey } = useWallet();
const requestAirdrop = async () => {
const signature = await
connection.requestAirdrop(publicKey, 1 * LAMPORTS_PER_SOL);
await connection.confirmTransaction(signature, 'confirmed');
}
return <button onClick={requestAirdrop}>Airdrop</button>
}
И ваш тест может нацелиться на эту кнопку, как только адаптер будет подключен.
Другой вариант — инициализировать адаптер парой ключей, которую вы предварительно загрузили с devnet SOL. Таким образом, что-то вроде этого
new E2EWalletAdapter({
keypair: <your_keypair_object>
})
Это также удобно, если вы хотите запустить набор тестов в определенном порядке, но ваша программа автоматизации обновляет браузер после каждого теста, например. Только убедитесь, что вы безопасно обращаетесь со всеми закрытыми ключами 🕵️♀️.
После этого вы можете выбрать любой E2E-фреймворк, который вам больше нравится, некоторые из наиболее используемых — Cypress, Puppetteer, TestCafe или Selenium, каждый из которых имеет свои особенности, так что выбирайте тот, который больше всего соответствует вашим потребностям.
И конечно, убедитесь, что вы не запускаете тесты в продакшене, так как они будут использовать реальный SOL, хотя если вы дочитали до этого момента, вы все равно не будете этого делать. Верно? Верно!
Как и в большинстве статей в интернете, это мое личное мнение, а не мнение компании Jet.
На этой ноте, о Jet Procol: Jet — это протокол ликвидности с открытым исходным кодом, не требующий хранения, который расширяет границы децентрализованных финансов и эффективности рынков заемного капитала. Ознакомьтесь с ним, если он вас заинтересовал!
Свяжитесь с нами
🌐 Посетите нас на сайте JetProtocol.io 🌐
📩 Пишите нам по адресу hello[at]JetProtocol[dot]io 📩
💬 Общайтесь с нами в Telegram или Discord 💬
🐦 Найдите нас в Twitter — @JetProtocol 🐦
Подпишитесь на нашу рассылку: https://jetprotocol.substack.com