Birim testine veya teste dayalı geliştirmeye değer mi?


48

İş yerindeki ekibim Scrum'a taşınıyor ve diğer ekipler birim testleri ve kullanıcı kabul testleri kullanarak test odaklı bir gelişim göstermeye başlıyor. UAT'leri severim, ancak genel olarak test odaklı geliştirme veya test odaklı geliştirme için birim testinde satılmam.

Test yazma ekstra bir iş gibi görünüyor, insanlara gerçek kodu yazarken bir koltuk değneği veriyor ve çok sık etkili olmayabilir.

Birim testlerinin nasıl çalıştığını ve nasıl yazacağını anlıyorum, ancak herkes bunun gerçekten iyi bir fikir olduğunu ve çaba ve zamana değdiğini iddia edebilir mi?

Ayrıca TDD'yi özellikle Scrum için iyi yapan bir şey var mı?


27
Yazılımınızın sık sık bozulduğundan, neredeyse hiç anlaşılmaz olduğundan ve gerçekten üretime hazır olmadan önce değiştirilmesinden kaynaklandığından emin olmak istiyorsanız; o zaman tamamen ünite testlerinden vazgeçmenizi ve TDD'yi öğrenmek için zaman ayırmamanızı öneririm.
Dawood ibn Kareem

3
Bir refaktör için istek / ihtiyaç hakkında düşünün. Yanlışlıkla bir şey kırdığınızda sizi yakalamak için kapsamlı bir birim test seti ile veya onsuz yeniden düzenlemeyi (herhangi bir büyüklükte) yaparken gerçekten daha emin misiniz?
Marjan Venema 17:12

2
"İnsanlara gerçek kod yazarken bir koltuk değneği verir"? Can en iyi uygulamalar bu şekilde tarif edilebilir?
user16764

4
@DavidWallace: Bu, TDD eksikliği değil, beceriksiz geliştiricilerin sorunu. Dahası, TDD yoğun bir şekilde kullanılsa bile, yaptığınız değişikliğin hiçbir şeyi bozmadığı konusunda sıfır garanti veriyor.
Kodlayıcı

6
@NimChimpsky: TDD'ye karşı herhangi bir olumsuzluğum yok, sadece yutturmaca takip etmiyorum. Olumlu yanları ve olumsuzları da var. Yanlış güvenlik duygusu bunlardan biri.
Kodlayıcı

Yanıtlar:


68

Kısa Cevap: Kesinlikle olumlu.

Uzun Cevap: Birim testleri, iş yerimde denediğim ve etkilediğim en önemli uygulamalardan biri (büyük banka, döviz ticareti). Evet onlar ekstra iş, ama tekrar tekrar para ödeyen iş. Otomatik birim testleri yalnızca yazdığınız kodu çalıştırmanıza yardımcı olur ve elbette beklentilerinizi doğrulamaz, aynı zamanda sizin veya bir başkasının yapabileceği gelecekteki değişiklikler için bir tür bekçi köpeği görevi görür. Testin bozulması, birisi kodu istenmeyen şekillerde değiştirdiğinde ortaya çıkar. Birim testlerinin göreceli değerinin, bir kod tabanında beklenen değişim ve büyüme seviyesi ile bağlantılı olarak azaldığını düşünüyorum, ancak beklenen değişimin düşük olduğu yerlerde bile, kodun neye yarar sağladığının ilk doğrulaması. Birim test değeri ayrıca kusurların maliyetine de bağlıdır. Bir hatanın maliyeti (maliyetin zaman / para / itibar / gelecek çabası kaybı olduğu durumlarda) sıfır ise, bir testin göreceli değeri de sıfırdır; ancak bu, ticari bir ortamda neredeyse hiçbir zaman böyle değildir.

Genelde artık işlerinin bir parçası olarak rutin olarak birim testleri oluşturmayan insanları işe almıyoruz - bu sadece her gün ortaya çıkmak gibi beklediğimiz bir şey. Birim testlerinin yapılmasının (biri beni bir tane göstermekte özgürsün) saf bir maliyet faydası analizi görmedim, ancak ticari bir ortamda, kodlama işlemlerini büyük bir sistemde kanıtlayabilmenin değerli olduğunu söyleyebilirim. . Ayrıca, yazdığım kodun (belirli bir seviyeye kadar) çalıştığını ve birisinin değişmesi durumunda herhangi bir beklenmedik yan etki nedeniyle kırılmış bir yapıya karşı uyarılacağını bildiğim için gece daha iyi uyumamı sağlıyor.

Test odaklı gelişme, aklımda bir test yaklaşımı değildir. Aslında çıktı, çalışma sistemi ve bir birim test seti olmakla birlikte bir tasarım yaklaşımı / uygulamasıdır. Geliştirilmesi oldukça zor ve mükemmel bir beceri olduğu için bu uygulama için daha az dindarım. Şahsen bir sistem inşa ediyorsam ve nasıl çalışacağı konusunda net bir fikrim yoksa, karanlıkta yolumu bulmama yardımcı olmak için TDD'yi kullanacağım. Ancak eğer mevcut bir kalıp / çözümü uyguluyorsam, genellikle yapmam.

Birim testler yazmanın mantıklı bir kanıtı olmaması durumunda, uzun bir süre boyunca denemenizi ve faydaları kendiniz yaşamanızı tavsiye ederim.


5
Eklemek istediğim şey, birim testinin ayrıca arayüz tasarımınız hakkında düşünmenizi sağlamasıdır. “Özel yöntemleri nasıl test ederim?” Diye düşündüğünüz bir bölüme ulaştığınızda, muhtemelen arayüzünüzün yanlış olduğunu biliyorsunuzdur.
TC1

1
"Uzun bir süre boyunca denemenizi ve faydalarını kendiniz yaşamanızı tavsiye ediyorum." Bir kere denemek benim için yeterliydi, faydaları açık görünüyordu.
NimChimpsky

1
+1 "Genelde artık çalışmalarının bir parçası olarak birim testler oluşturmayan insanları işe almıyoruz". Geçenlerde, diğer eksikliklerin yanı sıra, otomatik testler yazmaktan hoşlanmadığını, çünkü zaman kaybettikleri ve kodu kendisinin test edebileceğini kesinlikle ilan eden bir adayı reddetmek zorunda kaldım.
ftr

4
Eğer olamaz kanıtlamak aşikar olmayan kod bu işleri sadece otomatik testler kullanılarak ilgili herhangi bir şekilde. Otomatikleştirilmiş testlerde, yalnızca kodun testleri geçtiğini kanıtlayabilirsiniz - eğer testler kullanım durumlarınızın% 100'ünü kapsıyorsa, muhtemelen "belirli seviyeniz" vardır, ancak bu hala "kanıtlanabilir kod" anlamına gelmez. Gerçek bir kanıtlanabilirliğe sahip olmak için, en.wikipedia.org/wiki/Formal_verification - ihtiyacınız olacak, burada "kanıtlanabilir" terimini burada yanlış kullanıyorsunuz.
vaxquis

1
@vaxquis evet, ispat teriminin kullanımı konusunda kesinlikle haklısınız. Ancak, testlerin (veya TDD uygulamasının) varlığının, çalışan bir sistemin testlerin yokluğundan daha iyi olduğunun kanıtı olduğuna bahse girerim.
rupjones

16

Daha önce bulunan hatalar, daha sonra bulunan hatalardan daha az maliyetlidir. TDD, sisteminizin doğruluğunu doğrulamanıza yardımcı olur. Biraz daha ön yatırım yapıyorsun, ama sonra geri alırsın. Grafik biraz abartılı, ancak fikri iyi gösteriyor.

görüntü tanımını buraya girin

Görüntü Kaynağı


Geleneksel derken ne demek istiyorsun ? TDD olmayan bir şey var mı?
Giorgio

Bu grafik bazı gerçek istatistiklere dayanıyor gibi görünmüyor, yalnızca 2006'da bu Blog girişini yazan tek bir kişinin deneyimini temsil ediyor. Tamamen yanlış olduğunu söylemiyorum ama çok daha karmaşık.
Doktor Brown

9

Birim teste veya teste dayalı geliştirmeye değer mi?

Evet öyle . Bob Amca (Robert C Martin) bir sunumda;

Bir geliştiricinin kodunu test etmek ve bağırmaktan, şarkı söylemekten veya dans etmekten daha iyi bir şekilde yazmak için daha iyi çalıştığını kanıtlaması için.

Ve sen, test silmeye gidiş değildir çünkü sürece testi emin işlevselliği çalıştığını olduğu bir geçiş olduğu gibi - regresyon sorunları çözülür.

Üzerine yazılmış çok fazla şey var.

  1. Bu özelliğin çalışmasından siz sorumlusunuz. Bir test yaz. Sadece yap.
  2. Birim Testleri Entegrasyon Testi ile ne zaman değiştirilir?

SCRUM, Birim testi ve TDD ile ilişkili mi?

Kısacası, usta olduğunuzda Unit testingsize yakın olacaksınız TDD. SCRUM'un bununla hiçbir ilgisi yok, ama dedikleri gibi, harika şeyler iyi karışıyor, bu yazılım geliştirme teknikleri mükemmel bir yığına giriyor , eğer henüz denemediyseniz.

TDD'yi SCRUM için özellikle iyi yapan bir şey var mı?

Yukarıda söylediğim gibi iyi bir kombinasyon oluşturuyorlar ; Bazı otomasyon testleri eklerseniz , o zaman daha özel olur .


8

Test yazma ekstra bir iş gibi görünüyor, insanlara gerçek kodu yazarken bir koltuk değneği veriyor ve çok sık etkili olmayabilir.

Ünite testi koltuk değneği olarak değere sahiptir. Uygulamanızın gerektiği gibi çalışmayı bırakacağından korkmadan uygulamanızı değiştirmenize olanak tanıyan geliştirme çabalarınızı destekler. Birim testleri, uygulamanızın gereklilikleri karşıladığını doğrulayabileceğiniz bir araç sunduğundan, bir koltuk değnekinden de çok daha fazla bir şeydir.

Tüm testler (birim testleri, kabul testleri, entegrasyon testleri vb.) Sadece bunları kullanan kişiler kadar etkilidir. Çalışmanıza özensiz yaklaşırsanız, testleriniz özensiz olacak ve uygulamanızın sorunları olacaktır. Ne gereği var? Testleri zahmete sokuyorsunuz, çünkü kendinize ve müşterilerinize yazılımınızın çalıştığını kanıtlamanız gerekiyor ve yazılımın kullanılmasını engelleyebilecek herhangi bir sorun bulunmuyor. Evet, testler kesinlikle fazladan bir iştir, ancak sınamaya nasıl devam ettiğiniz, sürümün ardından hataları düzeltmek için ne kadar çaba harcayacağınızı ve kodunuzun değişmesi ve korunması için ne kadar çaba gerektireceğini belirler.

Birim testlerinin nasıl çalıştığını ve nasıl yazacağını anlıyorum, ancak herkes bunun gerçekten iyi bir fikir olduğunu ve çaba ve zamana değdiğini iddia edebilir mi?

TDD ve gerçekten kodlamadan önce testler yazmanızı gerektiren herhangi bir yöntem, gelecekteki teknik borçların ödenmesi için erken bir çaba olarak erken bir çaba harcadığınız yaklaşımı benimsemiştir. Projede çalışırken, kaçırılan veya iyi uygulanmayan herhangi bir şey, gelecekteki maliyetleri ve kaynak temin etme gereksinimlerini doğrudan etkileyen, artan bakım zorluğu şeklinde daha fazla teknik borçlanmaya neden olacaktır. Teste çıkmak, yalnızca gelecekteki teknik borcu ele almak için çaba harcamanızı sağlamakla kalmaz, aynı zamanda gereksinimlerinizi sadece kodunuzu çalıştırarak doğrulanabilecek şekilde kodlamanızı sağlar. İlk olarak Test, size sorunu kodda çözmeyi taahhüt etmeden önce sorunlu alan hakkındaki anlayışınızı doğrulama fırsatı verir ve uygulama çabalarınızı onaylar.

Kodunuzun işletme değerini en üst düzeye çıkarmak için gerçekten aşağı geliyor. Büyük ölçüde test edilmemiş ve bakımı zor olan kod, genellikle piyasaya sürüldükten sonra ürünün kullanım ömrü boyunca sürdürmek için ucuz ve hızlı bir şekilde üretilebilir ve çok maliyetlidir. Ünite düzeyinde iyice test edilmiş olan kodun oluşturulması genellikle daha pahalıdır, ancak serbest bırakıldıktan sonra ürünün kullanım ömrü boyunca sürdürülmesi nispeten düşüktür.

Ayrıca, TDD'yi SCRUM için özellikle iyi yapan bir şey var mı?

TDD, belirli bir metodoloji için spesifik olarak iyi değildir. Bu sadece bir araçtır. Özel sonuçlarınıza ulaşmanıza yardımcı olmak için gelişim süreçlerinize entegre edebileceğiniz bir uygulama. Bu nedenle, sorunuzu yanıtlamak için TDD, SCRUM veya başka bir yaklaşım olup olmadığı yönteminize ücretsizdir.


6

İnsanlar bunun ekstra bir çaba olduğunu düşünüyor, çünkü bu bir ön etkinlik. Zamanla kaybedeceğiniz şey, daha sonra tekrar kazanırsınız.

Birim sınama nedenlerim arasında ayrıca:

Size bir hedef verir: Yazılımın ne yapması gerektiğini bilmiyorsanız bir test yazamazsınız. Bu, daha sonra değil, spesifikasyonlardaki sorunları ayıklamanıza yardımcı olur.

Size bir ilerleme hissi verir.

Bir kod değişikliği diğer kod alanlarının çıktısını değiştirdiğinde sizi uyarır. Bu yeniden düzenlemeyi kolaylaştırır.

Ek bir dokümantasyon katmanı sağlar (özellikle testlerinizi doğru bir şekilde yorumlarsanız).

Her türlü iyi uygulamayı teşvik eder. Sınamaların hızlı çalışması gerektiğinden, ayrıştırılmış ve alaycı destekleyen kodlar yazmanızı teşvik eder. Bütün bunlar refactoring'e yardımcı olur.

Bu konudaki diğer yazılarda kapsanan başkaları da var. Buna değer.


2

Birim testine veya teste dayalı geliştirmeye değer mi?

Kesinlikle evet (diğer cevaplara bakınız)

Gerçekten iyi bir fikir ve çabaya ve zamana değer mi?

  • Evet , yeni bir şey başlatırsanız (yeni bir modül veya tamamen yeni bir uygulama ekleyin)
  • Hayır , halihazırda test güdümlü olmayan ve genişletilmesi gereken çok sayıda mevcut kod varsa (eski).

Kanımca test geliştirme, kanuni üniteden önce ünite testlerini yazarsanız daha etkili olur . Bu şekilde, testleri yerine getiren kod, test edilebilen minimum harici referanslarla açıkça ayrılır.

Kod, ünite testleri olmadan zaten mevcutsa, ünite testlerini yazmak için genellikle çok fazla iş gerekir, çünkü kod kolay test için yazılmamıştır.

TDD yaparsanız, kod otomatik olarak test edilebilirdir.


2

Buna diğer taraftan yaklaşmama izin ver. Birim testleri olmadan önemsiz olmayan bir uygulama geliştirdiğinizde ne olur? İyi bir QA departmanınız varsa, gerçekleşecek ilk şeylerden biri, çok sayıda bildirilen sorun olduğunu görmenizdir. Neden yaptığın şeyi test etmediğin ve işe yarayacağını varsaydığın için ve gerekliliklere çok fazla dikkat etmediğin için ve başvurunun onları karşılamadığı için. Tekrar yazmak ve düzeltmek için çizim tahtasına geri dönün. Şimdi düzeltmeleri yaptınız ve yepyeni bir sorun kümesi buldunuz, çünkü düzeltmelerinizin KG'ye gönderilmeden önce başka hiçbir şeyi etkilemediğini doğrulamak için hiçbir imkanınız yoktu. Maalesef son tarih geldi ve geçti ve yönetim bozuldu.

İyi bir KG departmanınız yoksa, durum daha kötüdür çünkü kullanıcılar hataları bulacaklardır ve sadece patronunuzu mutsuz edecek değil, üretim ortamını dizlerine ve 100'lerin hatta binlerce insanın bulunduğu yere getirebilir ünite testinin önleyeceği hataları giderirken durma. Bu iyi bir kariyer seçimi değil.

Şimdi bu kovboy yaklaşımının yıllarca sürdüğünü varsayalım. Şimdi, her değişiklik, hatta önemsiz olanlar bile, yeni ve beklenmeyen bir sorun yaratıyor gibi görünüyor. Sadece bu değil, uygulamanın daha iyi çalışmasını sağlamak için yapmak istediğiniz şeylerin birçoğu, yapamazsınız çünkü çok riskli ya da çok pahalılar ya da her ikisi de. Böylece yamaları sisteme daha kıvrımlı ve daha titiz ve kullanımı daha zor hale getiren yamaları koydunuz.

Kullanıcılar zaman tahminlerinizi sorgulamaya başlarlar; çünkü gittikçe büyüyüp büyürler ve sistemin böylesine karmaşık bir karmaşa haline geldiğini açıklamak zordur, değişiklikleri bile yapacakları yeri bulmak bile zordur ve hala yapamadıklarından emin olmak için daha da zorlaşır. başka bir şeyi kırma.

Böyle bir yerde çalıştım, on yıllık bir gelişimden sonra, gerçek sorunları çözmek için yapmak istediğimiz hemen hemen hiçbir şey yapılamadı, çünkü yüzlerce kişiselleştirilmiş istemci uygulamasının hangisini bozacağını söyleyemedik. İlk geliştiriciler çok "geliştirici ünite testleri, kıyametçi testine ihtiyacımız yok" geliştiricileriydi. Onları takip eden herkes kısa görüşlülüğü sayesinde acı çekti.

Ünite testleri olmadan, yazılım hatalıdır ve başlangıçta gelişmesi ve bakımı hem de daha uzun sürer. Neden dünya üzerinde birim testleri yapmak istemiyorsun? Testi yazmak için harcadığınız zaman, daha önce bulmanız gereken sorunları gidermek için harcayacağınız zamandan çok daha az olacaktır (hata ne kadar erken bulunursa düzeltmek için o kadar az zaman alır) ve testleri yazarak tamamen kaçınmanız gereken sorunlar ilk önce kodlamaya başlamadan önce gereksinimlerin daha iyi anlaşılmasını sağlar.


1

Yazdığınız kodun bir noktada test edilmesi gerekir. Her şeyi tek seferde yazmak ve ardından derleme düğmesine basıp parmaklarınızı çarpmak istemezsiniz. Küçük bloklar yazıp derlersiniz ve kodunuzda özenle hazırlanmış girdiler gönderir ve ne düşündüğünüzü yaptığını doğrularsınız. Sonra, genellikle geçici test cihazınızı siler ve bir sonraki bileşene geçer.

Ünite testi ile bu süreci basitleştirir ve testlerinizi sürdürmeniz için size bir bahane sunar. Bu şekilde, geçmişte test ettiğiniz şeyleri kıran herhangi bir değişiklik yaparsanız, kodunuzun diğer bölümlerini etkilemesine izin vermek yerine, bu gerilemeyi açıkça yakalayabilirsiniz. Bunda gerçek bir değer var.

TDD'ye kırmızı-yeşil-refactor yaklaşımı gelince, bunu biraz sıkıcı buluyorum. Ama her biri kendi.


1
2c için: Testlerin gerçekten işe yarayıp yaramadığını bilmek için, sınavdan geçmeden önce başarısız olduklarını görmeniz gerekir. Ne yazık ki, birçok geliştiricinin çalışıyor gibi görünen testler yazdığına tanık oldum, ancak test koşulları değiştirildiğinde, başarısız olmasına rağmen kod hala testi geçecekti. Test önce başarısız olursa ve ikinci olarak geçerse, o zaman hatasız bir test yazmanız daha olasıdır. Kod değiştirildikten sonra testi değiştirirseniz, kodun sağlam olduğundan emin olamazsınız. Evet sıkıcı, ama daha iyi olma şansı var. :-)
S.Robins

0

Geliştiriciler bulduğum çoğu zaman test yazma fikrine karşı dayanıklıdır. Testlerin hiçbir değeri olmadığını savunacakları kadar değil, sadece belirli bir sorunun nasıl çözüleceğini çözmenin bir yolu olduklarını söylüyorlar. Genellikle bu sorun içeriğe göre değişir. Bu yapıldıktan sonra testler bir amaca hizmet etmeyecek ve silinebilecekler. İşte meslektaşlarımın geçmişte ne zaman test yazacağına nasıl karar vereceğine dair verdikleri bağlamlardan bir örnek ve bunlara göre mümkün olan tek cevabı bulacaksınız:

  • Eldeki problem, yığın veya hesap makinesi gibi TDD için bir ders kitabı örneği olmalıdır
  • önemsiz kod test edilmemelidir (önceki argümanı geçersiz kılar)
  • Kritik veya zor kod ayrıntılı bir şekilde test edilmelidir (önceki tartışmada belirtilen)
  • Testler, yeniden düzenlemenin yapılmasına olanak sağlamak için uygulamaya önceden bağlanmamalıdır (önceki argümanı geçersiz kılar)
  • Belirli bir taşıma kapasitesine sahip üçüncü taraf bir servisi aramak gibi yan etkiler için test yapmak gerekli değildir (bu nedenle kara kutu testi yapılmaz)

Aslında genel olarak kabul gördüğümü ve sonuçta işe yaramaz olduğuna inandığım bir tür test var. Yani, selenyum, web sürücüsü, watir veya arquillian gibi GUI tabanlı testler. TDD projelerimdeki 5 dakikalık üretim döngüsünden ziyade 7 saatlik yapım döngüsünü böyle elde ediyoruz.

Bu aynı mesajlar genellikle diğer herkesle kodun ne kadar kötü olduğu ve önceki cihazların ne kadar beceriksiz olması gerektiğinden şikayet eder. Ayrıca bir beyaz tahta, MS ofisi veya bir wiki kullanarak uygun bir tasarım yapmanız ve bu tasarımın güncel kalması için büyük özen göstermeniz son derece önemlidir.

Sonuncusu, bu tür şeylerin sahtekarlık olduğunu anlamamı sağlayan şey. Birim testi olmayan herhangi bir tasarım belgesini hepimiz biliyoruz, güncel hale gelecektir ve yapılacak bakım masrafları nedeniyle güncel tutulmayacaktır. Aslında, kod yazmadan önce ve sonra kullanışlı ve okunaklı olan MS office formatında tasarım fikirlerini ifade etmenin iyi bir yolunu bulmaya çalıştım ve denedim. Her durumda başarısız oldum ve bir MS ofis belgesi üretmeyi başaran insanlar olsa da, aslında hiçbir zaman yararlı olmadı.

Demek, bir seçeneğin var. 10 yıllık geliştirme deneyimime dayanarak bu tür belgeleri üretmek için bilinen ve kanıtlanmış tek yöntem olan TDD'yi uygulayarak tasarım ve dokümantasyon yapabilirsiniz. Ya da politikaya girebilirsin.


1
Testler dokümantasyon değildir. TDD iyi bir uygulamadır, ancak çok fazla sayıda devs çok basitleştirilmiş test saplamalarına tüküren otomatik gen araçlarını kullanır. Buna karşı dirençli bir cihazınız varsa, ince taneli testler yazmak yerine, tüm ürünün daha fazlasını uygulayan daha büyük bir test cihazı yazmayı deneyin. Bunu açıkça faydalı bulacaklar. Yine de uygun belgeler yazmak zorundasınız, bundan kurtulmak yok.
gbjbaanb

@gbjbaanb: Eğer geliştiriciler auto-gen araçları kullanıyorlarsa, birim testleri yazabilirler, fakat kesinlikle TDD değil. TDD'de yöntemlerden önce test yazmanız gerekir. Henüz var olmayan bir yöntemin testini karıştırmayı otomatikleştiremezsiniz. Ayrıca iyi yazılmış testler de dokümantasyondur (kullanım kılavuzu gerektirmeyen, projenin diğer geliştiricileri için teknik dokümantasyon). İyi yazılmış ve sürdürülen birim testleri, yöntemlerin nasıl test edilmesi gerektiğini gösterir. Ve eğer testler düzenli olarak kontrol edilir ve başarılırsa, eski dokümantasyonlardan açıkça daha kesindirler. Bunu inkar edemezsin.
kriss

unittests, api'nin nasıl kullanılabileceğine dair örnekler gösterdikleri için çok iyi bir geliştirici belgesi olabilir.
k3b

Selenyum, web sürücüsü, vb. Nokta, web sitesinde manuel olarak QA yapmak zorunda olmamanızdır. Yani onları derleme sürecinizden çıkararak zaman kazanmazsınız, çünkü onların zaman kazancı olması gerekir.
Muhd
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.