Masalah apa yang dipecahkan oleh pengujian antarmuka pengguna otomatis?


23

Kami sedang menyelidiki pengujian antarmuka pengguna otomatis (saat ini kami melakukan pengujian unit dan integrasi otomatis).

Kami telah melihat Selenium dan Telerik dan telah memilih yang terakhir sebagai alat pilihan karena perekamnya yang jauh lebih fleksibel - dan kami tidak ingin penguji menulis terlalu banyak kode.

Namun, saya mencoba memahami manfaat secara keseluruhan. Apa pandangan orang dan hal-hal apa yang berfungsi dengan baik dan apa yang tidak?

Sistem kami sedang dalam pengembangan konstan dan kami secara berkala merilis versi baru platform kami (berbasis web).

Sejauh ini manfaat utama yang bisa kita lihat adalah untuk pengujian regresi, terutama di beberapa penyebaran klien platform kami.

Benar-benar mencari pandangan orang lain. Kami "berpikir" itu adalah hal yang benar untuk dilakukan tetapi dalam jadwal yang sudah sibuk mencari beberapa wawasan tambahan.


4
Bukankah istilah "pengujian otomatis" menyiratkan masalah yang coba dipecahkannya? // OTOH, jika Anda bertanya tentang ROI yang melekat pada "pengujian otomatis", itu pertanyaan yang berbeda ...
Jim G.

Jawaban:


24

Ketika tim saya menerapkan pengujian UI otomatis, banyak hal hebat terjadi.

Pertama, tim QA menjadi jauh lebih efisien dalam menguji aplikasi serta lebih mahir dengan aplikasi tersebut. Pimpinan QA mengatakan bahwa ia dapat mempercepat anggota QA baru dengan memperkenalkan mereka ke ruang tes untuk UI.

Kedua, kualitas tiket QA yang kembali ke tim Dev lebih baik. Alih-alih 'Halaman rusak ketika saya mengklik tombol Kirim' kami mendapat kasus yang tepat yang gagal sehingga kami bisa melihat apa yang dimasukkan ke dalam formulir. Tim QA juga mengambil langkah lebih jauh dengan memeriksa semua kasus yang gagal dan menguji skenario lain di sekitar halaman itu untuk memberi kita pandangan yang lebih baik tentang apa yang terjadi.

Ketiga, tim QA punya lebih banyak waktu. Dengan waktu tambahan ini, mereka dapat mengikuti lebih banyak pertemuan desain. Ini pada gilirannya memungkinkan mereka untuk menulis case test suite baru pada saat yang sama ketika Dev sedang mengkode fitur-fitur baru tersebut.

Selain itu, pengujian stres yang dilakukan oleh suite uji kami layak untuk diukur dengan emas. Jujur membantu saya tidur lebih nyenyak di malam hari mengetahui bahwa aplikasi kami dapat mengambil cukup banyak apa pun yang dilemparkan padanya. Kami menemukan beberapa halaman yang melawan tekanan yang bisa kami perbaiki sebelum ditayangkan. Sempurna.

Hal terakhir yang kami temukan adalah bahwa dengan beberapa penyesuaian oleh tim QA, kami juga dapat melakukan beberapa pengujian injeksi SQL pada aplikasi kami. Kami menemukan beberapa kerentanan yang dapat diperbaiki dengan cepat.

Pengaturan suite uji UI membutuhkan waktu yang cukup lama. Tapi, begitu ada di sana itu menjadi bagian sentral dari proses pengembangan kami.


1
+1 untuk menjelaskan langkah-langkah untuk membuat ulang pengujian yang gagal menjadi intrinsik dalam proses (poin kedua Anda)
IThasTheAnswer

Satu masalah: Tidakkah unit UI pengujian memblokir kemungkinan perubahan di UI [mengunci Anda] ... meskipun saya tidak memilih karena Anda menggambarkan manfaatnya dengan cara di mana keseluruhan runtime aplikasi sedang dipantau oleh unit test daripada komponen individual dari sistem yang diuji.
monksy

@monksy - Paket tes yang kami gunakan (saya tidak ingat namanya untuk masa pakai saya) tidak berdasarkan koordinat. Itu cukup pintar untuk menggunakan elemen id. Selama kami memberikan semua nama elemen UI kami, dan menyimpan nama-nama itu melalui revisi desain, kasus uji masih berfungsi. Kami membayar sangat mahal untuk perangkat lunak itu, tetapi kami merasa fitur itu sepadan.
Tyanna

1
@Tyanna Percayalah pada saya ... ini. Saya sudah mencoba untuk mengotomatiskan pengujian UI [untuk pengujian regresif] berdasarkan lokasi. Itu tidak berhasil, dan cukup membuat frustrasi. Tapi saya mengacu pada komponen bergerak di sekeliling, mengubah tampilan / UI, dan UI yang dapat
disesuaikan

13

Tes UI otomatis adalah tes integrasi nyata . Mereka menguji seluruh sistem dengan cara yang sebenarnya digunakan saat itu hidup. Itu membuat mereka ujian paling bermakna. Namun, mereka juga cenderung paling rapuh, dan paling lambat untuk dieksekusi.

Mengawasi rasio biaya / manfaat (dengan kerapuhan menjadi bagian dari biaya) dan jangan bimbang untuk memiliki beberapa hal yang diuji hanya secara manual (tapi pastikan mereka yang diuji). Dan jika memungkinkan, memungkinkan pengembang untuk menjalankan bagian tertentu dari UI test suite terhadap versi aplikasi yang berjalan secara lokal, sehingga mereka dapat memperoleh manfaat dari pengujian selama pengembangan.

Memiliki tes yang dijalankan secara otomatis pada server build (setidaknya sekali sehari) tentu saja merupakan keharusan mutlak.

kami tidak ingin penguji menulis terlalu banyak kode.

IMO ini adalah mimpi pipa. Membuat tes otomatis adalah menulis kode. Fungsi perekaman dapat membantu Anda menulis beberapa kode lebih cepat dan memulai lebih cepat dengan menuliskannya secara manual (dan memperlambat Anda jika Anda kehilangan titik di mana penulisan kode secara manual menjadi lebih cepat), tetapi pada akhirnya menulis kode secara manual adalah apa yang akan Anda akhiri. melakukan banyak hal. Lebih baik berharap kerangka pengujian Anda mendukungnya dengan baik dan pengembangannya tidak terlalu terfokus pada mimpi pipa (sangat dapat dijual) yang memungkinkan orang yang tidak dapat menulis kode untuk menghasilkan tes otomatis.


13

dan kami tidak ingin penguji menulis terlalu banyak kode

Kami mengambil pendekatan yang berlawanan. Kami ingin penguji menulis kode.

Inilah alur kerja yang mulai kami adopsi. Tidak mudah melakukan ini karena manajemen tidak sepenuhnya bergantung pada pengujian otomatis front-end. Mereka bersedia menerima "cukup dekat".

  1. Cerita pengguna.

  2. Konsep operasional. Bagaimana ceritanya akan bekerja. Ulasan desain.

  3. Sketsa layar: desain UI. Bagaimana kelihatannya.

  4. Naskah Selenium. Jika skrip semuanya berfungsi, kita sudah selesai dengan rilisnya.

  5. Pengodean dan pengujian hingga skrip bekerja.

Pengujian otomatis adalah satu - satunya cara untuk menunjukkan bahwa fungsi itu ada.

Pengujian manual rawan kesalahan dan harus ditimpa oleh manajemen: "cukup baik, tes gagal itu tidak terlalu penting sebanyak melepaskannya tepat waktu."

"Fitur program apa pun tanpa tes otomatis tidak ada."

Presentasi visual adalah cerita lain. Pengujian manual terhadap tata letak visual adalah kasus luar biasa karena mungkin melibatkan penilaian estetika atau melihat masalah spesifik (kecil) pada layar penuh piksel yang sangat besar dan kompleks.


2
"penguji menulis cek otomatis". Begitulah cara penguji harus melakukan pekerjaan mereka. "penguji pernah mendapat kesempatan untuk menguji" tidak masuk akal bagi saya. Bisakah Anda menjelaskan apa artinya ini?
S.Lott

3
@ S.Lott: mungkin pengujian manual. Pengujian otomatis bagus, tetapi tidak semuanya. Itu tidak dapat menemukan banyak mode kesalahan yang tidak terduga (seperti masalah tata letak). Dan saya akan mengatakan bahwa fundamentalisme yang ditampilkan dalam dua kalimat terakhir adalah kontraproduktif.
Michael Borgwardt

11
Automated testing is the only way to demonstrate that the functionality exists.Bukan itu. Pengujian eksplorasi atau pengujian yang dilakukan secara manual menunjukkan fungsionalitas yang ada. Ini tidak sebagus pengujian otomatis, tetapi pengujian otomatis bukan satu-satunya cara untuk menguji.
StuperUser

1
@ S.Lott - Michael dan StuperUser melakukannya dengan benar. Pengujian manual dan lebih baik eksplorasi.
Lyndon Vrooman

1
-1 untuk fundamentalisme, seperti yang dikatakan Michael. Lihat joelonsoftware.com/items/2007/12/03.html untuk penjelasan betapa konyolnya sikap itu ketika dibawa ke kesimpulan logisnya.
Mason Wheeler

5

Sejauh ini manfaat utama yang bisa kita lihat adalah untuk pengujian regresi, terutama di beberapa penyebaran klien platform kami.

Mengotomatiskan pengujian regresi Anda adalah hal yang baik. Ini membebaskan penguji Anda untuk melakukan pekerjaan yang lebih menarik - baik dengan menambahkan lebih banyak tes otomatis, menguji stres aplikasi Anda, atau sejumlah hal lainnya.

Selain itu, dengan membuatnya otomatis, Anda dapat membuat pengembang menjalankan tes dan karenanya mencegah masalah hanya ditemukan kemudian dalam proses.


Pengalaman apa yang Anda miliki bahwa mempertahankan tes regresi otomatis membebaskan penguji untuk melakukan pekerjaan yang lebih menarik? Saya tahu ini teorinya, tetapi jika perlu berhari-hari untuk menulis atau memodifikasi tes versus hanya melakukan pengujian manual, mungkin itu tidak akan berhasil.
IThasTheAnswer

@Tunic - Kami menggunakan Silverlight dalam proyek kami saat ini dan saya sedang menulis beberapa tes saat ini yang memeriksa ikatan antara XAML dan kode tampilan model C #. Ini akan berarti bahwa penguji kami tidak perlu memeriksa bahwa nilai-nilai yang mereka masukkan diformat dengan benar, dll. Ini masih awal, tetapi terlihat menjanjikan.
ChrisF

5

Kami telah melihat Selenium dan Telerik dan telah memilih yang terakhir sebagai alat pilihan karena perekamnya yang jauh lebih fleksibel

Saya tidak yakin seberapa banyak Anda telah melihatnya. Tentunya ada opsi lain juga. Sudahkah Anda melihat ke Watir , WatiN , Sikuli untuk beberapa nama?

dan kami tidak ingin penguji menulis terlalu banyak kode.

Saya merasa sedih untuk orang-orang yang harus memelihara skrip ini. Paling sering, tanpa kode yang dapat dengan mudah dimodifikasi, skrip menjadi rapuh dan mulai membutuhkan waktu lebih lama untuk memodifikasi skrip daripada untuk merekam ulang, yang menghabiskan lebih banyak waktu.

Namun, saya mencoba memahami manfaat secara keseluruhan. Apa pandangan orang dan hal-hal apa yang berfungsi dengan baik dan apa yang tidak?

Otomatisasi uji adalah hal yang indah bila dilakukan dengan benar. Menghemat waktu pada tes regresi / pemeriksaan sehingga memberi penguji Anda lebih banyak waktu untuk melakukan yang terbaik, uji. Tapi jangan percaya sejenak bahwa itu adalah peluru perak. Script otomasi membutuhkan waktu yang signifikan untuk dikembangkan jika aplikasi sudah ada tetapi tes tidak, dan memerlukan pembaruan konstan dengan setiap rilis. Tes otomatis juga merupakan cara yang bagus bagi orang-orang baru di tim untuk melihat bagaimana sistem seharusnya berperilaku. Selain itu, pastikan penguji Anda memutuskan apa yang perlu diotomatisasi. Jika ini adalah cek kecil yang tidak perlu banyak untuk diperiksa, sangat monoton, dan mudah untuk diotomatisasi, mulailah dengan itu. Mulailah selalu dengan cek yang mendapatkan hasil maksimal melalui otomatisasi, dan mulai dari sana.

Sejauh ini manfaat utama yang bisa kita lihat adalah untuk pengujian regresi, terutama di beberapa penyebaran klien platform kami.

Ini adalah manfaat utama, dan jika diatur dengan benar, dapat menguji sebagian besar peramban yang Anda perlukan dengan perubahan konfigurasi kecil.

Kami "berpikir" itu adalah hal yang benar untuk dilakukan tetapi dalam jadwal yang sudah sibuk mencari beberapa wawasan tambahan.

Seperti yang saya katakan sebelumnya, otomatisasi pengujian membutuhkan banyak upaya, namun, ketika dilakukan dengan benar, saya belum pernah bertemu tim yang mengatakan "Saya berharap kita belum membuat otomatisasi pengujian kami."


2
+1 terutama untuk "Saya merasa tidak enak bagi orang-orang yang harus memelihara skrip ini". Kode yang dirancang dengan baik adalah bagian penting dari penulisan tes UI yang dapat dipelihara, terutama dengan UI yang sering berubah. Jika penguji OP tidak dapat menggunakan Obyek Halaman atau menggunakan kembali kode, saya akan dengan serius menyarankan OP untuk mempertimbangkan hanya mengotomatisasi UI yang stabil (jika ada).
Ethel Evans

3

Anda benar bahwa regresi sangat besar. Juga -

  • jika tes Anda ditulis secara modular, Anda bisa mendapatkan lebih banyak uang dengan mencampur dan mencocokkan set tes

  • kami telah menggunakan kembali skrip pengujian otomatis untuk memuat data sehingga kami tidak perlu mengumpulkan data untuk melakukan pengujian ukuran besar

  • uji kinerja

  • tes multi-thread

  • pada sistem web - bertukar antar browser dan bertukar antar OS. Dengan masalah konsistensi peramban, memukul basis selebar mungkin adalah hal yang sangat besar.

Hal-hal yang harus dilewati - terutama dalam sistem web, perhatikan kasus-kasus di mana elemen tampilan Anda dibuat dengan id yang dinamis dan berubah - seringkali skrip pengujian otomatis tidak menangani hal ini dengan baik, dan Anda mungkin perlu beberapa perancangan ulang yang serius untuk memperbaruinya.


+1 untuk poin pertama Anda. Sangat penting untuk rangkaian uji otomasi yang sukses!
Lyndon Vrooman

Ya, setujui poin pertama. Telah mempertimbangkan poin kedua dan ketiga sebenarnya tetapi saya pikir ini adalah di mana Telerik jatuh. Skrip selenium (dapat yang sederhana) dapat digunakan oleh BroswerMob
IThasTheAnswer

3

Hanya satu contoh: secara akurat mengukur durasi rendering halaman web

Menggunakan tes otomatisasi, jauh lebih mudah untuk menguji kinerja browser web. Untuk mengukur waktu respons maksimum yang mungkin Anda terima, cukup tetapkan konstanta dalam skrip pengujian Anda, dan / atau berikan sebagai parameter fungsi, misalnya dalam pseudocode ini: $ sel-> wait_for_page_to_load ($ mypage, $ maxtime).

Melakukan pengujian lintas browser dengan nilai rendah bisa sangat mencerahkan.

Alternatifnya adalah meminta karyawan membuat pengukuran waktu dengan stopwatch.


3

Pengujian Antarmuka Pengguna Otomatis memecahkan kemampuan untuk:

  • dengan cepat mengulangi pengujian sejumlah besar komponen
  • ingatlah untuk menguji sejumlah besar fungsi setiap kali
  • bandingkan menjalankan dan menjalankan waktu test suites saat aplikasi tumbuh
  • set up berjalan dengan ratusan input dan kondisi variabel yang berbeda
  • memungkinkan orang yang tidak menulis tes untuk menjalankannya dan melihat masalah visual apa pun
  • memungkinkan pengguna akhir untuk melihat aplikasi yang digunakan dengan cara yang cepat dan mudah
  • mendistribusikan uji UI yang dijalankan ke jaringan, server jarak jauh atau layanan
  • mulai pengujian volume menggunakan mesin paralel.

Namun, seperti yang telah dicatat orang lain:

Telerik ...

alat pilihan karena perekamnya yang jauh lebih fleksibel

adalah bendera merah bagi banyak dari kita.

Script yang direkam dengan cara ini cenderung bukan solusi jangka panjang karena:

  • database / objek ID cenderung berubah dari kasus ke kasus
  • skrip yang direkam secara manual sering mengandalkan tag tata letak halaman yang sering berubah
  • tindakan umum perlu ditulis berulang kali alih-alih mengizinkan penggunaan kembali (lihat pendekatan SitePrism & PageObject)
  • terkadang Anda perlu menggunakan alat seperti xpath untuk mengambil informasi tambahan berdasarkan informasi halaman saat ini. Skrip rekaman sederhana tidak akan melakukan ini.
  • pengembang dan penguji yang menulis kode tidak akan didorong untuk menggunakan kelas CSS, ID dan atribut data HTML5, yang merupakan praktik yang akan mengarah pada pengujian yang lebih kuat dan dapat dipertahankan.

Telerik memang memiliki beberapa keunggulan yang harus dipertimbangkan:

  • ditujukan untuk klien seluler
  • alat bawaan untuk mengelola pertumbuhan
  • menangani Android, iOS dan Windows Phone

Suatu pendekatan yang dapat membantu menjembatani kesenjangan adalah untuk merekam skrip awal menggunakan alat perekam halaman tetapi kemudian mengubah skrip untuk menggunakan ID, kelas dan atribut data sehingga akan bertahan dari waktu ke waktu. Ini adalah pendekatan yang sebenarnya saya gunakan dengan plugin selenium firefox.


2

Itu membuat "Pengujian Pakar" (mirip dengan "pengujian Eksplorasi", tetapi dilakukan oleh pengguna akhir atau anggota tim dengan banyak pengetahuan bisnis) lebih mudah untuk dilakukan, mencatat hasil, mengukur dan mengotomatisasi.


2

Saya datang pada ini dari latar belakang yang berbeda. Di mantan majikan saya, kami mengembangkan alat pengujian otomatis komersial (QALoad, QARun, TestPartner, SilkTest, SilkPerfomer).

Kami melihat pengujian UI otomatis sebagai mengisi dua peran:

  1. Pengujian regresi penuh

  2. Pengaturan otomatis lingkungan pengujian

Kami sangat bergantung pada alat untuk melakukan tes regresi setiap malam. Kami benar-benar tidak memiliki sumber daya manusia untuk menguji semua tombol dan dialog untuk memverifikasi kami tidak mematahkan apa pun antara UI dan logika bisnis.

Untuk tes yang lebih penting, kami menemukan bahwa satu orang dapat memutar beberapa VM dan menggunakan skrip untuk sampai ke titik tes yang sebenarnya. Itu membiarkan mereka fokus pada bit-bit penting dan tidak mencoba dan mengikuti test case 24 langkah.

Satu-satunya masalah dengan pengujian otomatis adalah kebiasaan membuang terlalu banyak tes ke dalam kotak tanpa pengawasan untuk menghilangkan duplikat atau tes yang tidak perlu. Sesekali kita harus masuk dan memangkas kembali sehingga suite bisa selesai dalam waktu kurang dari 12 jam.


2

Pengujian otomatis, dalam bentuk apa pun, menyediakan pengujian regresi; dengan menjalankan tes yang dulu berfungsi, Anda memverifikasi itu masih berfungsi (atau tidak) terlepas dari apa pun yang telah Anda tambahkan. Ini benar terlepas dari apakah tes tersebut merupakan tes integrasi (yang biasanya tidak menyentuh UI) atau AAT (yang biasanya memerlukan UI).

Pengujian UI otomatis memungkinkan sistem untuk diuji seolah-olah pengguna mengklik tombol. Dengan demikian, pengujian semacam itu dapat digunakan untuk memverifikasi navigasi melalui sistem, kebenaran label dan / atau pesan, kinerja dan / atau waktu pemuatan dalam lingkungan pengujian tertentu, dll. Tujuan utama adalah untuk mengurangi waktu yang dihabiskan orang dengan mengklik tombol tombol QA, seperti halnya tes integrasi dan unit untuk programmer. Dia dapat mengatur satu tes satu kali (biasanya dengan merekam klik tetikus sendiri dan entri data ke dalam skrip), dan setelah tes bekerja dengan baik semua yang harus dia lakukan untuk memverifikasi kebenaran sistem yang diuji menjalankannya lagi. Beberapa kerangka kerja, seperti Selenium, memungkinkan tes untuk dimigrasi di antara browser, memungkinkan untuk pengujian beberapa lingkungan di mana situs harus berfungsi dengan baik.

Tanpa pengujian otomatis, Anda dibatasi oleh jumlah dan kecepatan penguji QA Anda; mereka harus benar-benar memiliki sistem, menguji bahwa fitur baru Anda memenuhi persyaratan dan (sama pentingnya) bahwa Anda tidak merusak apa pun yang sudah ada di sana.


0

Pengujian menentukan banyak hal berbeda. Banyak dari tes ini dapat diotomatisasi, untuk memungkinkan penghapusan pekerjaan yang membosankan, dan untuk mendapatkan lebih banyak dilakukan. Untuk menentukan apakah pengujian Anda dapat dilakukan secara otomatis, Anda harus terlebih dahulu melihat apakah pertanyaan yang diajukan sesuai untuk itu.

  • Apakah Anda menentukan apakah suatu komponen berfungsi sesuai dengan spesifikasi?
  • Apakah Anda ingin menguji semua input dan output yang mungkin berbeda?
  • stress test komponennya?
  • Atau apakah Anda mencoba menguji bahwa "itu berhasil"?

Sebagian besar dapat diotomatisasi, karena sifatnya mekanis. Fungsi baru menerima input, jadi apa yang terjadi ketika kita melemparkan data acak padanya? Tetapi beberapa, seperti pengujian jika sistem bekerja, mengharuskan seseorang untuk benar-benar menggunakannya . Jika tidak, Anda tidak akan pernah tahu apakah harapan pengguna Anda sama dengan harapan program. Sampai, yaitu, sistem 'rusak'.


-1

Dalam pengalaman saya, pengujian antarmuka pengguna otomatis mencakup banyak celah termasuk:

  • Kurangnya dokumentasi (contoh: menggunakan test runner otomatis untuk mendemonstrasikan fungsionalitas yang ada)
  • Persyaratan usang karena creep lingkup (contoh: mengidentifikasi kesenjangan antara persyaratan dan kode dengan menangkap layar selama tes berjalan)
  • Pergantian pengembang dan penguji yang tinggi (contoh: JavaScript reverse engineering lawas dengan menangkap layar selama pengujian berjalan dengan alat pengembang terbuka)
  • Mengidentifikasi pelanggaran konvensi penamaan standar melalui tes regresi XPath (contoh: mencari semua node atribut DOM untuk nama yang disurvei unta)
  • Mengenali celah keamanan yang hanya dapat ditemukan oleh komputer (contoh: logout dari satu tab sambil mengirimkan formulir secara bersamaan)

1
Apa manfaatnya dengan hal-hal ini? Alangkah baiknya jika Anda bisa menguraikan sedikit.
Hulk

-1

Saya ingin berbagi pengalaman tim kami. Kami telah menggunakan alat pengujian UI kami sendiri, Screenster, untuk menguji milik kami dan aplikasi web pelanggan kami. Ini telah membuktikan dirinya sebagai alternatif yang bermanfaat untuk Selenium untuk tugas pengujian visual / CSS. Screenster adalah alat otomatisasi pengujian yang melakukan perbandingan berbasis screenshot dari berbagai versi halaman web Anda. Pertama, ia membuat garis dasar visual untuk sebuah halaman, mengambil tangkapan layar untuk setiap tindakan pengguna. Selama menjalankan berikutnya dibutuhkan tangkapan layar baru di setiap langkah, bandingkan dengan yang dari baseline dan menyoroti perbedaan.

Ringkasnya, Screenster memiliki keuntungan sebagai berikut: Basis visual: tangkapan layar ditangkap untuk setiap langkah pengguna selama perekaman pengujian. Perbandingan berbasis tangkapan layar: Screenster membandingkan gambar yang diambil selama pemutaran dengan yang dari baseline dan menyoroti semua perbedaan. Selektor Smart CSS: tester dapat memilih Elemen CSS pada tangkapan layar dan melakukan tindakan dengannya - mis. Tandai sebagai mengabaikan wilayah untuk dikecualikan dari perbandingan lebih lanjut

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.