인프런 커뮤니티 질문&답변

syrose00님의 프로필 이미지

작성한 질문수

Do It! 장고+부트스트랩: 파이썬 웹개발의 정석

소스코드 위치

self.client.post에 글이 생성되지않습니다

작성

·

238

·

수정됨

0

강의 영상과 똑같이 작성했음에도 last_post의 내용이 client가 생성한 post가 아닌, post_003의 내용이 들어가면서 Failed가 발생합니다.

실행결과 Failed

self.assertEqual(last_post.title, 'Post Form 만들기')

AssertionError: '세 번째 포스트 입니다.' != 'Post Form 만들기'

- 세 번째 포스트 입니다.

+ Post Form 만들기

[test.py 코드]

from time import sleep
from django.test import TestCase, Client
from bs4 import BeautifulSoup
from .models import Post, Category, Tag
from django.contrib.auth.models import User


class TestView(TestCase):
    def setUp(self):
        self.client = Client()
        # 사용자 생성
        self.user_yunju = User.objects.create_user(
            username='yunju',
            password='0129'
        )
        self.user_subin = User.objects.create_user(
            username='subin',
            password='cute0313'
        )
        self.user_yunju.is_staff = True
        self.user_yunju.save()

        # 카테고리 생성
        self.category_programming = Category.objects.create(
            name='programming', slug='programming'
        )
        self.category_music = Category.objects.create(
            name='music', slug='music'
        )

        # 태그 생성
        self.tag_python_kar = Tag.objects.create(
            name="파이썬 공부", slug='파이썬-공부'
        )
        self.tag_python = Tag.objects.create(
            name="python", slug='python'
        )
        self.tag_django = Tag.objects.create(
            name="django", slug='django'
        )

        # 포스트 생성
        self.post_001 = Post.objects.create(
            title="첫 번째 포스트 입니다.",
            content="Hello World! We are the World",
            author=self.user_yunju,
            category=self.category_programming
        )
        self.post_001.tags.add(self.tag_django)

        self.post_002 = Post.objects.create(
            title="두 번째 포스트 입니다.",
            content="저는 마라탕과 떡볶이를 사랑합니다",
            author=self.user_subin,
            category=self.category_music
        )
        self.post_003 = Post.objects.create(
            title="세 번째 포스트 입니다.",
            content="Category가 없는 포스트입니다.",
            author=self.user_subin
        )
        self.post_003.tags.add(self.tag_django)
        self.post_003.tags.add(self.tag_python)

    # 내비게이션바 함수
    def navbar_test(self, soup):
        navbar = soup.nav
        self.assertIn('Blog', navbar.text)
        self.assertIn('Blog', navbar.text)

        logo_btn = navbar.find('a', text='Do It Django')
        self.assertEqual(logo_btn.attrs['href'], '/')

        home_btn = navbar.find('a', text='Home')
        self.assertEqual(home_btn.attrs['href'], '/')

        blog_btn = navbar.find('a', text='Blog')
        self.assertEqual(blog_btn.attrs['href'], '/blog/')

        about_me_btn = navbar.find('a', text='About me')
        self.assertEqual(about_me_btn.attrs['href'], '/about_me/')

    # 카테고리 카드 함수
    def category_card_test(self, soup):
        categories_card = soup.find('div', id='categories-card')
        self.assertIn('Categories', categories_card.text)
        self.assertIn(
            f'{self.category_programming}({self.category_programming.post_set.count()})',
            categories_card.text
        )
        self.assertIn(
            f'{self.category_music}({self.category_music.post_set.count()})',
            categories_card.text
        )
        self.assertIn(
            f'미분류({Post.objects.filter(category=None).count()})',
            categories_card.text
        )

    # 포스트가 있는 경우
    def test_post_list_with_posts(self):
        self.assertEqual(Post.objects.count(), 3)

        response = self.client.get('/blog/')
        self.assertEqual(response.status_code, 200)

        soup = BeautifulSoup(response.content, 'html.parser')
        self.assertIn('Blog', soup.title.text)

        self.navbar_test(soup)
        self.category_card_test(soup)

        main_area = soup.find('div', id='main-area')

        post_001_card = main_area.find('div', id='post-1')
        self.assertIn(self.post_001.title, post_001_card.text)
        self.assertIn(self.post_001.category.name, post_001_card.text)
        self.assertIn(self.tag_django.name, post_001_card.text)
        self.assertNotIn(self.tag_python.name, post_001_card.text)
        self.assertNotIn(self.tag_python_kar.name, post_001_card.text)

        post_002_card = main_area.find('div', id='post-2')
        self.assertIn(self.post_002.title, post_002_card.text)
        self.assertIn(self.post_002.category.name, post_002_card.text)
        self.assertNotIn(self.tag_django.name, post_002_card.text)
        self.assertNotIn(self.tag_python.name, post_002_card.text)
        self.assertNotIn(self.tag_python_kar.name, post_002_card.text)

        post_003_card = main_area.find('div', id='post-3')
        self.assertIn(self.post_003.title, post_003_card.text)
        self.assertIn('미분류', post_003_card.text)
        self.assertIn(self.tag_django.name, post_003_card.text)
        self.assertIn(self.tag_python.name, post_003_card.text)
        self.assertNotIn(self.tag_python_kar.name, post_003_card.text)

        self.assertIn(self.post_001.author.username.upper(), main_area.text)
        self.assertIn(self.post_002.author.username.upper(), main_area.text)

    # 포스트가 없는 경우
    def test_post_list_without_posts(self):
        Post.objects.all().delete()
        self.assertEqual(Post.objects.count(), 0)

        response = self.client.get('/blog/')
        self.assertEqual(response.status_code, 200)

        soup = BeautifulSoup(response.content, 'html.parser')
        self.navbar_test(soup)
        self.assertIn('Blog', soup.title.text)

        main_area = soup.find('div', id='main-area')
        self.assertIn('아직 게시물이 없습니다.', main_area.text)

    # 상세페이지 함수
    def test_post_detail(self):
        self.assertEqual(Post.objects.count(), 3)

        self.assertEqual(self.post_001.get_absolute_url(), '/blog/1/')

        response = self.client.get(self.post_001.get_absolute_url())
        self.assertEqual(response.status_code, 200)

        soup = BeautifulSoup(response.content, 'html.parser')
        self.navbar_test(soup)
        self.category_card_test(soup)

        self.assertIn(self.post_001.title, soup.title.text)

        main_area = soup.find('div', id='main-area')
        post_area = main_area.find('div', id='post-area')

        self.assertIn(self.post_001.title, post_area.text)
        self.assertIn(self.post_001.category.name, post_area.text)

        self.assertIn(self.user_yunju.username.upper(), post_area.text)
        self.assertIn(self.post_001.content, post_area.text)

        self.assertIn(self.tag_django.name, post_area.text)
        self.assertNotIn(self.tag_python.name, post_area.text)
        self.assertNotIn(self.tag_python_kar.name, post_area.text)

    # 카테고리별 페이지 나타내는 함수
    def test_category_page(self):
        response = self.client.get(
        self.category_programming.get_absolute_url())
        self.assertEqual(response.status_code, 200)
        soup = BeautifulSoup(response.content, 'html.parser')

        self.navbar_test(soup)
        self.category_card_test(soup)

        main_area = soup.find('div', id='main-area')
        self.assertIn(self.category_programming.name, main_area.h1.text)
        self.assertIn(self.category_programming.name, main_area.text)
        self.assertIn(self.post_001.title, main_area.text)
        self.assertNotIn(self.post_002.title, main_area.text)
        self.assertNotIn(self.post_003.title, main_area.text)

    # 태그 페이지를 나타내는 함수
    def test_tag_page(self):
        response = self.client.get(self.tag_django.get_absolute_url())
        self.assertEqual(response.status_code, 200)
        soup = BeautifulSoup(response.content, 'html.parser')

        self.navbar_test(soup)
        self.category_card_test(soup)

        self.assertIn(self.tag_django.name, soup.h1.text)
        main_area = soup.find('div', id='main-area')
        self.assertIn(self.tag_django.name, main_area.text)

        self.assertIn(self.post_001.title, main_area.text)
        self.assertNotIn(self.post_002.title, main_area.text)
        self.assertIn(self.post_003.title, main_area.text)

    # 로그인하지 않은 사용자에 대한 폼 제한 함수
    def test_create_post_without_login(self):
        response = self.client.get('/blog/create_post/')
        self.assertNotEqual(response.status_code, 200)

    # 폼(form)을 이용한 포스트 작성 페이지 생성
    # 로그인한 사용자만 폼 작성 가능
    def test_create_post_with_login(self):
        self.client.login(username='yunju', password='0129')
        response = self.client.get('/blog/create_post/')
        self.assertEqual(response.status_code, 200)

        soup = BeautifulSoup(response.content, 'html.parser')
        self.assertEqual('Create Post - Blog', soup.title.text)
        main_area = soup.find('div', id='main-area')
        self.assertIn('Create a New Post', main_area.text)
        
        self.client.post(
            '/blog/create_post/',
            {
                'title': 'Post Form 만들기',
                'content': 'Post Form 페이지를 만듭시다.',
            },
        )

        last_post = Post.objects.last()
        self.assertEqual(last_post.title, 'Post Form 만들기')
        self.assertEqual(last_post.author.username, 'yunju')
        self.assertEqual(last_post.content, 'Post Form 페이지 만들어보자!')

[views.py 코드]

from django.core.exceptions import PermissionDenied
from django.shortcuts import render, redirect
from django.views.generic import ListView, DetailView, CreateView, UpdateView
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from .models import Post, Category, Tag

# 리스트를 출력하는 django 기본 라이브러리
class PostList(ListView):
    model = Post
    ordering = '-pk'

    def get_context_data(self, **kwargs):
        context = super(PostList, self).get_context_data()
        context['categories'] = Category.objects.all()
        context['no_category_post_count'] = Post.objects.filter(
            category=None).count()
        return context

# 하나의 리스트를 불러오는 django 기본 라이브러리
class PostDetail(DetailView):
    model = Post

    def get_context_data(self, **kwargs):
        context = super(PostDetail, self).get_context_data()
        context['categories'] = Category.objects.all()
        context['no_category_post_count'] = Post.objects.filter(
            category=None).count()
        return context

# 포스트 생성 함수
class PostCreate(LoginRequiredMixin, UserPassesTestMixin, CreateView):
    model = Post
    fields = ['title', 'hook_text', 'content','head_image', 'file_upload', 'category']

    def test_func(self):
        return self.request.user.is_superuser or self.request.user.is_staff

    def form_valid(self, form):
        current_user = self.request.user
        if current_user.is_authenticated and (current_user.is_staff or current_user.is_superuser):
            form.instance.author = current_user
            return super(PostCreate, self).form_valid(form)
        else:
            return redirect('/blog/')

class PostUpdate(LoginRequiredMixin, UpdateView):
    model = Post
    fields = ['title', 'hook_text', 'content','head_image', 'file_upload', 'category']
    template_name = 'blog/post_update_form.html'
    def dispatch(self, request, *args, **kwargs):
        if request.user.is_authenticated and request.user == self.get_object().author:
            return super(PostUpdate, self).dispatch(request, *args, **kwargs)
        else:
            return PermissionDenied

# 카테고리별 페이지 반환 함수
def category_page(request, slug):
    if slug == 'no_category':
        category = '미분류'
        post_list = Post.objects.filter(category=None)
    else:
        category = Category.objects.get(slug=slug)
        post_list = Post.objects.filter(category=category)
        return render(
            request,
            'blog/post_list.html',
            {
                'post_list': post_list,
                'categories': Category.objects.all(),
                'no_category_post_count': Post.objects.filter(category=None).count(),
                'category': category
            }
        )

# 태그별 페이지 반환 함수
def tag_page(request, slug):
    tag = Tag.objects.get(slug=slug)
    post_list = tag.post_set.all()
    return render(
        request,
        'blog/post_list.html',
        {
            'post_list': post_list,
            'categories': Category.objects.all(),
            'no_category_post_count': Post.objects.filter(category=None).count(),
            'tag': tag
        }
    )

 

답변 1

0

SungYong Lee님의 프로필 이미지
SungYong Lee
지식공유자

안녕하세요. 작성하신 코드를 실행시켜봤는데, 그런 오류는 나오지 않았습니다. 혹시 urls.py가 잘못되어 있는건 아닐까요? 다른 문제가 없는지 확인해보시기 바랍니다.

그런데 그 문제 아니더라도 다른 문제들이 많았습니다. 말씀하신 test_create_post_with_login에서는 content에는 'Post Form 페이지를 만듭시다.' 로 되어 있고, 밑에 테스트 코드에는 'Post Form 페이지를 만들어보자!' 로 되어 있어서 다르다는 에러가 나옵니다.

그리고 category_card_test에서도 카테고리명 뒤에 띄어쓰기가 빠져있어서 잘못된 것으로 나옵니다.

 

 

syrose00님의 프로필 이미지

작성한 질문수

질문하기