Efisiensi Biaya Relatif Pengembangan (Penerimaan) Didorong Uji


15

Saya ingin tahu apa dampak keseluruhan dari perencanaan sumber daya pada proyek perangkat lunak, di mana persyaratan dan desain proyek didorong oleh tes penerimaan otomatis dan tes unit, berbeda dengan pendekatan yang lebih "tradisional" untuk pengembangan perangkat lunak.

masukkan deskripsi gambar di sini

Apa, dalam pengalaman Anda, efek keseluruhan pada persyaratan sumber daya untuk menyelesaikan proyek perangkat lunak di bawah TDD, yang bertentangan dengan metodologi pengembangan yang lebih "tradisional"? Tampak jelas bagi saya bahwa kualitas akan meningkat, dan jumlah ketidakpastian menurun karena pengujian dilakukan sebelumnya, tetapi memerlukan tes di muka sepertinya akan membutuhkan lebih banyak waktu pengembang untuk menyelesaikannya. Berapa peningkatan upaya pengembangan, atau apakah itu benar-benar menurun karena penghapusan bug di muka?

Berapa banyak upaya yang diperlukan dari pelanggan? Apakah mereka harus mengubah cara mereka berhubungan dengan proyek, terutama jika mereka terbiasa dengan desain besar di depan? Apakah jumlah jam yang dibutuhkan pelanggan secara keseluruhan meningkat, atau apakah itu benar-benar berkurang?

Saya akan membayangkan bahwa perkiraan waktu akan sangat samar dalam proses TDD berulang pada awal proyek TDD (karena tidak ada Rencana Pengembangan Perangkat Lunak). Adakah titik, katakanlah, 20% dalam sebuah proyek, di mana kepercayaan diri meningkat cukup sehingga estimasi waktu dan uang yang lebih atau kurang stabil pada akhirnya dapat diberikan kepada pelanggan?

Catatan: Saya tidak mencari pendapat atau teori subjektif di sini, jadi tolong jangan berspekulasi. Saya mencari lebih banyak untuk pengalaman dunia nyata di TDD.


Saya yakin tidak ada data dunia nyata. Anda hanya mendapatkan pendapat dan teori subyektif berdasarkan pengalaman dunia nyata peoeple.
Euforia

1
@Euphoric: Saya mencari pengamatan objektif dan kenyataan berdasarkan pengalaman dunia nyata. Maaf saya tidak menjelaskannya. Namun, saya tidak perlu angka keras; Saya akan menerima kesan umum seperti: "sementara waktu pengembangan kami meningkat secara substansial, biaya pemeliharaan kami menurun karena perangkat lunak lebih dapat diandalkan dan pelanggan memahami perangkat lunak lebih baik karena mereka mengambil bagian dalam desain selama upaya pengembangan."
Robert Harvey

2
Jadi, apakah ini pertanyaan berbasis opini? Ini tentu terdengar seperti
BЈовић


@ BЈовић: Lihat paragraf terakhir di badan pertanyaan saya.
Robert Harvey

Jawaban:


11

Hal pertama yang perlu dinyatakan adalah bahwa TDD tidak serta merta meningkatkan kualitas perangkat lunak (dari sudut pandang pengguna). Ini bukan peluru perak. Ini bukan obat mujarab. Mengurangi jumlah bug bukanlah alasan kami melakukan TDD.

TDD dilakukan terutama karena menghasilkan kode yang lebih baik. Lebih khusus lagi, hasil TDD dalam kode yang lebih mudah untuk diubah .

Apakah Anda ingin menggunakan TDD atau tidak tergantung pada tujuan Anda untuk proyek tersebut. Apakah ini akan menjadi proyek konsultasi jangka pendek? Apakah Anda harus mendukung proyek setelah go-live? Apakah ini proyek sepele? Biaya tambahan yang ditambahkan mungkin tidak sepadan dalam kasus ini.

Namun, menurut pengalaman saya, proposisi nilai untuk TDD tumbuh secara eksponensial ketika waktu dan sumber daya yang terlibat dalam suatu proyek tumbuh secara linear.

Tes unit yang baik memberikan keuntungan sebagai berikut:

  1. Tes unit memperingatkan pengembang tentang efek samping yang tidak diinginkan.
  2. Tes unit memungkinkan pengembangan cepat fungsionalitas baru pada sistem yang lama dan matang.
  3. Tes unit memberi pengembang baru pemahaman kode yang lebih cepat dan lebih akurat.

Efek samping dari TDD mungkin lebih sedikit bug, tetapi sayangnya itu adalah pengalaman saya bahwa sebagian besar bug (terutama yang paling jahat) biasanya disebabkan oleh persyaratan yang tidak jelas atau buruk atau tidak perlu dicakup oleh putaran pertama pengujian unit.

Untuk meringkas:

Pengembangan pada versi 1 mungkin lebih lambat. Pengembangan pada versi 2-10 akan lebih cepat.


1
Saya suka penjajaran eksplisit "kode yang lebih baik" yang berbeda dari peningkatan "kualitas perangkat lunak", yaitu bahwa hal-hal nilai programmer dalam kode tidak selalu bahwa ia melakukan apa yang diinginkan pelanggan.

1
Bukankah tes penerimaan di muka dan tes unit seharusnya menjelaskan persyaratan?
Robert Harvey

@ RobertTarvey Mereka seharusnya tetapi tidak harus . Tes unit dan tes penerimaan akan mencerminkan pemahaman pengembang tentang persyaratan ketika mereka ditulis. Pengembang mungkin memiliki apa pun mulai dari pemahaman yang lengkap hingga tidak memahami persyaratan ketika mereka mulai menulis perangkat lunak. Bagian dari persamaan itu jauh lebih tergantung pada klien dan manajer produk daripada apa pun. Secara teoritis, tes harus banyak membantu. Dalam praktiknya, yah, "itu tergantung".
Stephen

1
Saya harus mengklarifikasi, kita berbicara tentang TDD secara terpisah di sini, bukan implementasi SCRUM yang menggabungkan TDD. Dalam isolasi, TDD adalah tentang menulis tes sehingga Anda menulis kode yang lebih baik dan dapat melakukan refactor lebih cepat dan lebih aman nanti.
Stephen

1
@Stephen: Mungkin saya seharusnya membuatnya lebih jelas bahwa saya sedang berbicara tentang rasa TDD yang menggabungkan tes penerimaan sebagai bagian dari proses pengumpulan persyaratan. Saya telah menambahkan grafik ke pertanyaan untuk membuatnya lebih jelas.
Robert Harvey

6

Ada bab dalam Pembuatan Perangkat Lunak tentang Pengembangan yang Didorong oleh Tes, yang mengutip makalah yang dibahas di sini .

Studi kasus dilakukan dengan tiga tim pengembangan di Microsoft dan satu di IBM yang telah mengadopsi TDD. Hasil dari studi kasus menunjukkan bahwa kepadatan cacat pra-rilis dari empat produk menurun antara 40% dan 90% relatif terhadap proyek serupa yang tidak menggunakan praktik TDD. Subyektif, tim mengalami peningkatan 15-35% dalam waktu pengembangan awal setelah mengadopsi TDD.

Apakah hasil ini dapat digeneralisasikan untuk kasus Anda, tentu saja, sesuatu yang akan diperdebatkan oleh pendukung TDD sudah jelas dan pencela TDD akan berdebat tidak benar.


4
Masalah dengan penelitian itu adalah mereka tidak menguji unit kode sebelum mengadaptasi TDD. TDD bukan alat ajaib yang mengurangi jumlah cacat hingga 40-90% hanya dengan mengadopsinya
BЈовић

1
@ BЈовић Saya tidak berpikir mereka mengklaim "sihir" di mana saja di koran itu. Mereka mengklaim bahwa beberapa tim mengadopsi TDD, beberapa tim tidak, mereka diberi pekerjaan "serupa" dan beberapa kepadatan cacat dan waktu pengembangan dicatat. Jika mereka memaksa tim non-TDD untuk menulis tes unit saja supaya semua orang memiliki tes unit, itu tidak akan menjadi studi yang valid secara ekologis.

Studi yang valid secara ekologis? Agak tergantung pada apa yang Anda ukur. Jika Anda ingin tahu apakah menulis tes Anda di depan penting, maka semua orang harus menulis tes unit, bukan hanya grup TDD.
Robert Harvey

1
@robert Harvey itu pertanyaan tentang variabel perancu, bukan validitas ekologis. Merancang percobaan yang baik melibatkan gradien yang tidak aktif. Sebagai contoh jika kelompok kontrol menulis unit test post hoc, orang akan berpendapat eksperimen itu tidak sehat karena kelompok kontrol bekerja dengan cara yang tidak biasa ditemukan di alam liar.

2
Untungnya saya tidak mengatakan itu.

5

Saya tidak memiliki makalah penelitian atau statistik untuk diberikan kepada Anda, tetapi saya akan menceritakan pengalaman saya bekerja di tim / organisasi yang secara historis memiliki cakupan tes unit rendah rata-rata dan tidak ada tes ujung ke ujung, dan secara bertahap memindahkan bilah ke tempat kita sekarang, dengan lebih banyak pendekatan ATDD (tetapi, ironisnya, bukan TDD tradisional).

Secara khusus, ini adalah bagaimana jadwal proyek digunakan untuk bermain (dan masih bermain di tim / produk lain dalam organisasi yang sama):

  • Analisis dan implementasi hingga 4 minggu
  • 2 minggu pengujian regresi, perbaikan bug, stabilisasi, dan rilis persiapan
  • 1-2 minggu memperbaiki kerusakan yang diketahui
  • 2-3 minggu pembersihan kode dan masalah / dukungan pasca produksi (cacat tidak diketahui / pemadaman yang tidak direncanakan)

Ini sepertinya overhead konyol, tetapi sebenarnya sangat umum, hanya sering ditutupi di banyak organisasi dengan QA yang hilang atau tidak efektif. Kami memiliki penguji yang baik dan budaya pengujian intensif, sehingga masalah ini ditangkap lebih awal, dan diperbaiki di muka (sebagian besar waktu), daripada diizinkan untuk bermain perlahan selama beberapa bulan / tahun. 55-65% overhead pemeliharaan lebih rendah daripada norma yang diterima secara umum yaitu 80% dari waktu yang dihabiskan untuk debugging - yang tampaknya masuk akal, karena kami memang memiliki beberapa unit test dan tim lintas fungsi (termasuk QA).

Selama rilis pertama dari produk terbaru tim kami, kami telah mulai melakukan retrofit tes penerimaan tetapi mereka tidak cukup untuk menghabisi dan kami masih harus bergantung pada banyak pengujian manual. Rilis ini agak kurang menyakitkan daripada yang lain, IMO sebagian karena tes penerimaan serampangan kami dan juga sebagian karena cakupan unit uji kami yang sangat tinggi relatif terhadap proyek lain. Namun, kami menghabiskan hampir 2 minggu untuk regresi / stabilisasi dan 2 minggu untuk masalah pasca produksi.

Sebaliknya, setiap rilis sejak rilis awal itu memiliki kriteria penerimaan awal dan tes penerimaan, dan iterasi kami saat ini terlihat seperti ini:

  • 8 hari analisis dan implementasi
  • 2 hari stabilisasi
  • 0-2 hari gabungan dukungan pasca pembersihan dan pembersihan

Dengan kata lain, kami mengalami peningkatan dari 55-65% overhead pemeliharaan ke 20-30% overhead perawatan. Tim yang sama, produk yang sama, perbedaan utama adalah peningkatan progresif dan perampingan tes penerimaan kami.

Biaya pemeliharaannya adalah, per sprint, 3-5 hari untuk analis QA dan 1-2 hari untuk pengembang. Tim kami memiliki 4 pengembang dan 2 analis QA, jadi (tidak termasuk UX, manajemen proyek, dll.) Itu maksimal 7 hari kerja dari 60 hari, yang saya akan kumpulkan hingga 15% biaya overhead implementasi hanya untuk berada di sisi aman.

Kami menghabiskan 15% dari setiap periode rilis mengembangkan tes penerimaan otomatis, dan dalam prosesnya dapat memotong 70% dari setiap rilis melakukan tes regresi dan memperbaiki bug pra-produksi dan pasca-produksi.

Anda mungkin memperhatikan bahwa timeline kedua jauh lebih tepat dan juga jauh lebih pendek daripada yang pertama. Itu adalah sesuatu yang dimungkinkan oleh kriteria penerimaan di muka dan tes penerimaan, karena sangat menyederhanakan "definisi selesai" dan memungkinkan kita untuk jauh lebih percaya diri dalam stabilitas rilis. Tidak ada tim lain yang (sejauh ini) berhasil dengan jadwal rilis dua mingguan, kecuali mungkin ketika melakukan rilis pemeliharaan yang cukup sepele (hanya perbaikan bug, dll.).

Efek samping lain yang menarik adalah kami dapat menyesuaikan jadwal rilis kami dengan kebutuhan bisnis. Suatu kali, kami harus memperpanjangnya menjadi sekitar 3 minggu untuk bertepatan dengan rilis lain, dan dapat melakukannya sambil memberikan lebih banyak fungsi tetapi tanpa menghabiskan waktu ekstra untuk pengujian atau stabilisasi. Di waktu lain, kami harus mempersingkatnya menjadi sekitar 1½ minggu, karena liburan dan konflik sumber daya; kami harus mengambil lebih sedikit pekerjaan dev, tetapi, seperti yang diharapkan, mampu menghabiskan lebih sedikit waktu untuk pengujian dan stabilisasi tanpa memperkenalkan cacat baru.

Jadi menurut pengalaman saya, tes penerimaan, terutama ketika dilakukan sangat awal dalam proyek atau sprint, dan ketika dirawat dengan baik dengan kriteria penerimaan yang ditulis oleh Pemilik Produk, adalah salah satu investasi terbaik yang dapat Anda lakukan. Tidak seperti TDD tradisional, yang orang lain benar menunjukkan lebih berfokus pada menciptakan diuji kode dari bebas cacat kode - ATDD benar-benar cacat membantu menangkap banyak lebih cepat; itu setara organisasi dengan pasukan penguji yang melakukan tes regresi lengkap setiap hari, tetapi jauh lebih murah.

Akankah ATDD membantu Anda dalam proyek jangka panjang yang dilakukan dalam gaya RUP atau (ugh) Waterfall, proyek yang berlangsung 3 bulan atau lebih? Saya pikir juri masih memilih yang itu. Dalam pengalaman saya, risiko terbesar dan paling jelek dalam proyek-proyek jangka panjang adalah tenggat waktu yang tidak realistis dan persyaratan yang berubah. Tenggat waktu yang tidak realistis akan menyebabkan orang mengambil jalan pintas, termasuk menguji jalan pintas, dan perubahan signifikan terhadap persyaratan kemungkinan akan membatalkan sejumlah besar tes, mengharuskan mereka untuk ditulis ulang dan berpotensi menggembungkan overhead implementasi.

Saya cukup yakin bahwa ATDD memiliki hadiah fantastis untuk model Agile, atau untuk tim yang tidak resmi tangkas tetapi memiliki jadwal rilis yang sangat sering. Saya belum pernah mencobanya pada proyek jangka panjang, terutama karena saya belum pernah atau bahkan pernah mendengar ada organisasi yang mau mencobanya pada proyek semacam itu, jadi masukkan disclaimer standar di sini. YMMV dan semua itu.

PS Dalam kasus kami, tidak ada upaya ekstra yang diperlukan dari "pelanggan", tetapi kami memiliki Pemilik Produk penuh waktu dan berdedikasi yang benar-benar menulis kriteria penerimaan. Jika Anda berada dalam bisnis "consultingware", saya menduga mungkin akan jauh lebih sulit untuk membuat pengguna akhir menulis kriteria penerimaan yang bermanfaat. Seorang Pemilik Produk / Manajer Produk sepertinya adalah elemen yang sangat penting untuk melakukan ATDD dan walaupun saya dapat sekali lagi hanya berbicara dari pengalaman saya sendiri, saya belum pernah mendengar ATDD berhasil dipraktikkan tanpa seseorang untuk memenuhi peran itu.


Ini sangat berguna, terima kasih. Tidak terpikir oleh saya bahwa ATTD dapat mengubah karakter dari upaya TDD, tetapi itu masuk akal, terutama ketika Anda mendengar tentang orang-orang yang mampu menghasilkan perangkat lunak yang ditulis dengan baik, relatif bebas bug tepat waktu dan sesuai anggaran tanpa tentu saja menggunakan unit testing secara luas.
Robert Harvey

@ RobertTarvey: Saya harus mengklarifikasi - kami masih membuat unit test, hanya saja tidak sebagai bagian dari proses TDD. Biasanya tes penerimaan didahulukan atau sejajar dengan pengembangan awal, kemudian kode selesai, kemudian tes unit dan refactoring. Saya terkadang berpikir bahwa TDD akan membantu pengembang tertentu menulis kode yang lebih baik, tetapi saya belum dapat mendukungnya. Meskipun saya dapat berbicara sendiri - saya sering menangkap banyak bug dan desain cacat dalam kode saya sendiri hanya selama proses penulisan unit test.
Aaronaught

1

Persyaratan Sumber Daya

Apa, dalam pengalaman Anda, efek keseluruhan pada persyaratan sumber daya untuk menyelesaikan proyek perangkat lunak di bawah TDD, yang bertentangan dengan metodologi pengembangan yang lebih "tradisional"?

Dalam pengalaman saya, biaya yang memerlukan tes dimuka segera dikurangi dengan keduanya mendefinisikan kriteria penerimaan yang jelas di muka, dan kemudian menulis untuk tes. Tidak hanya biaya pengujian dimitigasi dimuka saya juga menemukan itu umumnya mempercepat pengembangan keseluruhan. Meskipun peningkatan kecepatan tersebut dapat terhapus oleh definisi proyek yang buruk, atau perubahan persyaratan. Namun, kami masih dapat merespon dengan baik perubahan seperti itu tanpa dampak yang parah. ATDD juga secara signifikan mengurangi upaya pengembang dalam memverifikasi perilaku sistem yang benar melalui rangkaian uji otomatis dalam kasus berikut:

  • refaktor besar
  • peningkatan platform / paket
  • migrasi platform
  • peningkatan toolchain

Ini mengasumsikan tim yang akrab dengan proses dan praktik yang terlibat.

Keterlibatan Pelanggan

Berapa banyak upaya yang diperlukan dari pelanggan?

Mereka harus lebih terlibat secara berkelanjutan. Saya telah melihat pengurangan besar dalam investasi di muka, tetapi permintaan yang jauh lebih besar sedang berlangsung. Saya belum mengukur, tetapi saya cukup yakin adalah investasi waktu yang lebih besar bagi pelanggan.

Namun, saya telah menemukan hubungan pelanggan sangat meningkat setelah 5 atau lebih demo di mana mereka melihat perangkat lunak mereka perlahan terbentuk. Komitmen waktu dari pelanggan sedikit menurun seiring berjalannya waktu ketika hubungan dikembangkan, semua orang terbiasa dengan proses dan harapan yang terlibat.

Estimasi Proyek

Saya akan membayangkan bahwa perkiraan waktu akan sangat samar dalam proses TDD berulang pada awal proyek TDD (karena tidak ada Rencana Pengembangan Perangkat Lunak).

Saya telah menemukan bahwa biasanya pertanyaan tentang seberapa baik permintaan tersebut dan apakah pimpinan teknis mampu mengeluarkan (termasuk estimasi kartu) proyek. Dengan asumsi proyek ini terekam dengan baik dan Anda memiliki rata-rata kecepatan yang wajar dan standar deviasi, kami merasa mudah untuk mendapatkan perkiraan yang layak. Jelas semakin besar proyek, semakin tidak pasti karena itulah saya biasanya memecah proyek besar menjadi proyek kecil dengan janji untuk melanjutkan nanti. Ini jauh lebih mudah dilakukan setelah Anda menjalin hubungan dengan pelanggan.

Sebagai contoh:

"Sprint" tim saya adalah selama seminggu dan kami memiliki rata-rata berjalan dan std. deviasi selama 14 minggu terakhir. Jika proyek 120 poin, kami memiliki rata-rata 25 dan std. penyimpangan 6 maka memperkirakan penyelesaian suatu proyek adalah:

Project Total / (Mean Velocity - (2 * Std. Deviation) = 95% Time Estimate
120           / (25            - (2 * 6             ) = 9.2 weeks

Kami menggunakan 2 Std. Aturan praktis deviasi untuk estimasi kepercayaan 95% kami. Dalam praktiknya kami biasanya menyelesaikan proyek di bawah std pertama. penyimpangan, tetapi lebih dari maksud kami. Ini biasanya karena penyempurnaan, perubahan, dll.


Jadi pada dasarnya apa yang Anda katakan adalah bahwa TDD meningkatkan upaya pembangunan dengan mendorong pemangku kepentingan untuk melakukan hal-hal yang seharusnya mereka lakukan, seperti memberikan persyaratan yang jelas, dapat ditindaklanjuti, dan kriteria penerimaan.
Robert Harvey

1
Yah, bukan hanya itu. Seiring kemajuan proyek, peningkatan partisipasi memungkinkan untuk percakapan yang lebih baik antara pengembang dan pemangku kepentingan. Hal ini memungkinkan untuk hal-hal seperti menawarkan dev lebih murah secara bergantian karena pemahaman mereka tentang apa yang diinginkan pemangku kepentingan dapat disempurnakan lebih lanjut. Hal ini memungkinkan para pemangku kepentingan untuk mengubah persyaratan lebih awal karena mereka menyadari ada sesuatu yang hilang, atau tidak akan bekerja tanpa respons antagonis dari dev; dan tanpa banyak harapan yang tidak masuk akal yang biasanya datang dari para pemangku kepentingan.
dietbuddha

-1

membutuhkan tes di muka sepertinya akan membutuhkan lebih banyak waktu pengembang untuk menyelesaikannya. Berapa peningkatan upaya pengembangan, atau apakah itu benar-benar menurun karena penghapusan bug di muka?

Ini sebenarnya tidak benar. Jika pengembang Anda menulis tes unit (dan seharusnya), maka waktunya harus kira-kira sama, atau lebih baik. Saya mengatakan lebih baik, karena kode Anda akan sepenuhnya diuji, dan mereka harus menulis hanya kode untuk memenuhi persyaratan.

Masalah dengan pengembang adalah mereka cenderung untuk mengimplementasikan bahkan hal-hal yang tidak diperlukan untuk membuat perangkat lunak generik mungkin.

Berapa banyak upaya yang diperlukan dari pelanggan? Apakah mereka harus mengubah cara mereka berhubungan dengan proyek, terutama jika mereka terbiasa dengan desain besar di depan? Apakah jumlah jam yang dibutuhkan pelanggan secara keseluruhan meningkat, atau apakah itu benar-benar berkurang?

Itu seharusnya tidak masalah. Siapa pun yang melakukan persyaratan harus melakukannya sebaik mungkin.

Jika Anda melakukan cara pengembangan yang gesit, maka itu tidak berarti desain besar di depan. Namun, semakin baik persyaratan, arsitektur, dan desain dilakukan - kualitas kode akan meningkat, dan waktu untuk menyelesaikan perangkat lunak akan berkurang.

Karena itu, jika mereka suka melakukan BDUF, biarkan mereka melakukannya. Ini akan membuat hidup Anda lebih mudah sebagai pengembang.


1
Seperti yang saya pahami, TDD dan BDUF umumnya tidak kompatibel satu sama lain.
Robert Harvey

3
BDUF umumnya tidak kompatibel dengan praktik manajemen pembangunan yang baik. Tetapi akan mungkin untuk melakukan proyek BDUF secara TDD. TDD adalah teknik untuk membuat perangkat lunak berkualitas lebih baik sedangkan BDUF adalah teknik untuk persyaratan pemenuhan persyaratan. Teknik yang buruk, tapi tetap saja teknik.
Stephen

@RobertHarvey Benar, tetapi jika mereka ingin melakukan BDUF - itu adalah pilihan mereka. Jika Anda benar-benar melakukan lincah, maka Anda bebas untuk meningkatkan desain mereka, dan masih melakukan TDD.
BЈовић

jadi Anda mengatakan bahwa jika saya menulis unit test kode saya akan sepenuhnya diuji dan jika semua uji lulus, itu tentu saja berarti perangkat lunak bebas bug (atau setidaknya lebih baik). Jadi saya hanya perlu menguji setiap metode perangkat lunak saya misalnya "function testSqr () {int a = 3; assertTrue (mySqr (a) == 9);} berfungsi mySqr (int a) {return 9;}"
Dainius

@Dainius Tidak, baca lagi. Cakupan kode 100% tidak bebas bug. Ya, Anda perlu menguji setiap metode. Tentu saja, unit menguji akses basis data, GUI, dll tidak masuk akal. Tes unit bukan untuk itu.
BЈовић
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.