warto jest zrobić krok do tyłu i abstrakcyjny co a/B testin g próbuje zrobić zanim zanurzy się w kodzie. Czego dokładnie potrzebujemy do przeprowadzenia testu?
- cel, który ma warunek
- Przynajmniej dwie odrębne ścieżki aby osiągnąć cel Condition
- system do wysyłania widzów w dół jednej ze ścieżek
- system do zapisywania wyników testu
Mając to na uwadze, pomyślmy o wdrożeniu.
Cel
Kiedy myślimy o cel w internecie zazwyczaj mamy na myśli, że użytkownik osiągnie pewną stronę lub że ukończenia określonego działania, na przykład z powodzeniem rejestracji jako użytkownik lub uzyskanie do strona kasy.
W Django mogliśmy model, który w kilka sposobów - być może naiwnie wewnątrz widoku, wywołanie funkcji ilekroć cel został osiągnięty:
def checkout(request):
a_b_goal_complete(request)
...
Ale to nie pomaga, bo będziemy mieli aby dodać ten kod wszędzie tam, gdzie go potrzebujemy - i jeśli używamy dowolnych wtyczek, których nie chcemy edytować, aby dodać nasz test A/B.
Jak wprowadzić cele A/B bez bezpośredniego edytowania kodu widoku? A co z oprogramowaniem pośredniczącym?
class ABMiddleware:
def process_request(self, request):
if a_b_goal_conditions_met(request):
a_b_goal_complete(request)
To pozwoli nam śledzić cele A/B w dowolnym miejscu na stronie.
Skąd wiemy, że warunki celu zostały spełnione? Aby ułatwić implementację, zasugerujemy, że wiemy, że Cel spełnił warunki, gdy użytkownik dotrze do określonej ścieżki URL. Jako bonus możemy zmierzyć to bez brudzenia rąk w widoku. Aby powrócić do naszego przykładu z rejestracji użytkownika, moglibyśmy powiedzieć, że cel ten został osiągnięty, gdy użytkownik osiągnie ścieżkę URL:
/rejestracji/pełny
więc zdefiniować a_b_goal_conditions_met
:
a_b_goal_conditions_met(request):
return request.path == "/registration/complete":
Ścieżki
myśląc o Ścieżki w Django to naturalne, aby przejść do idei przy użyciu różnych szablonów. Czy jest jeszcze inny sposób, pozostaje do zbadania. W testach A/B robisz małe różnice między dwiema stronami i mierzysz wyniki. Dlatego najlepszym rozwiązaniem jest zdefiniowanie pojedynczego szablonu ścieżki podstawowej, z którego powinny rozciągać się wszystkie ścieżki do celu.
Jak wyrenderować te szablony? Najprawdopodobniej dobry jest dekorator - w Django najlepiej jest dodać parametr template_name
do swoich widoków, aby dekorator mógł zmienić ten parametr w czasie wykonywania.
@a_b
def registration(request, extra_context=None, template_name="reg/reg.html"):
...
Można zobaczyć ten dekorator albo introspekcję funkcję zawinięte i modyfikując template_name
argumentu lub patrząc odpowiednie szablony z gdzieś (jak model).Jeśli nie chcemy, aby dodać dekorator do każdej funkcji możemy zaimplementować to jako część naszego ABMiddleware:
class ABMiddleware:
...
def process_view(self, request, view_func, view_args, view_kwargs):
if should_do_a_b_test(...) and "template_name" in view_kwargs:
# Modify the template name to one of our Path templates
view_kwargs["template_name"] = get_a_b_path_for_view(view_func)
response = view_func(view_args, view_kwargs)
return response
Musielibyśmy też trzeba dodać jakiś sposób, aby śledzić, które widoki mają A/B testy uruchomione itp
system do wysyłania widzów ścieżką
teoretycznie jest to łatwe, ale istnieje wiele różnych implementacjach więc nie jest jasne, który z nich jest najlepszy. Wiemy, że dobry system powinien dzielić użytkowników równo po ścieżce - Należy użyć jakiejś metody hashowania - Być może mógłbyś użyć modułu licznika memcache podzielonego przez liczbę ścieżek - być może jest lepszy sposób.
System do zapisywania wyników testu
Musimy nagrać ilu użytkowników zszedł co Path - będziemy również potrzebować dostępu do tych informacji, gdy użytkownik osiągnie cel (musimy być w stanie powiedzieć, jaką Ścieżkę doszli, aby spełnić Warunek Celu) - użyjemy jakiegoś Modelu (-ów) do zapisywania danych oraz Django Sessions lub Cookies, aby zachować informacje o ścieżce, dopóki użytkownik nie dotrze do celu stan.
Zamykanie Thoughts
Dałem dużo pseudo kod do realizacji testów A/B w Django - powyższe nie jest bynajmniej kompletne rozwiązanie, ale dobry start w kierunku stworzenia ram dla wielokrotnego użytku/B w Django.
Dla odniesienia możesz chcieć spojrzeć na Siedem minut A/B Paula Mara na GitHub - jest to wersja ROR powyższego! http://github.com/paulmars/seven_minute_abs/tree/master
Aktualizacja
W dalszej refleksji i dochodzenie Google Website Optimizer to jest oczywiste, że istnieją dziury w powyższej logiki. Używając różnych szablonów do reprezentowania ścieżek, przełamujesz buforowanie w widoku (lub jeśli widok jest buforowany, zawsze będzie wyświetlał tę samą ścieżkę!). Zamiast tego, używając Ścieżek, zamiast tego kradnę terminologię GWO i używam idei Combinations
- czyli jednej konkretnej części zmiany szablonu - na przykład zmieniając znacznik strony na <h1>
.
Rozwiązanie obejmowałoby tagi szablonów, które renderowałyby się do JavaScript. Kiedy strona jest ładowana do przeglądarki, JavaScript przesyła żądanie do twojego serwera, który pobiera jedną z możliwych Kombinacji.
W ten sposób można przetestować wiele kombinacji na stronę, zachowując buforowanie!
Aktualizacja
Wciąż jest miejsce dla przełączania szablonu - powiedzmy na przykład pan wprowadzić zupełnie nową stronę główną i chce przetestować to występ przeciwko starym głównej - ty, że nadal chcesz używać technika przełączania szablonów. Należy pamiętać o tym, że trzeba będzie wymyślić sposób przełączania się między X liczby buforowanych wersji strony. Aby to zrobić, należy zastąpić standardowe buforowane oprogramowanie pośredniczące, aby sprawdzić, czy jest to test A/B działający pod żądanym adresem URL.Wtedy może wybrać poprawną wersję z pamięci podręcznej do pokazania !!!
Aktualizacja
Korzystanie idee opisane powyżej mam wdrożył aplikację podłączany za podstawowy testowania A/B Django. Można dostać go GitHub:
http://github.com/johnboxall/django-ab/tree/master
Ale to wymaga modyfikacji wszystkich poprzednich istnial widoki prawda? Nie chcę tego robić. Czy istnieje alternatywny sposób, aby mój stary kod pozostał tak jak on i to ab-testowanie stoi na szczycie tego? –
Można napisać własną wersję render_to_response, jak przypuszczam, która wchodzi w interakcje z tym dekoratorem, aby osiągnąć to, co chcesz. Dodam próbkę kodu do mojej odpowiedzi, aby zademonstrować. –
Justin: obie sugestie są doskonałe. Maddy: jeśli chcesz A/B przetestować całą witrynę, to nie, będziesz musiał ugryźć bullet gdzieś w łańcuchu żądania/odpowiedzi i programowo, lub deklaratywnie, wskazać, które szablony odpowiadają numerom "ui". –